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 $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 + #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 +4.1.8 - Released 29 March 2005 -some cases of ICMP checksum alteration were wrong +include path from Phil Dibowitz for sorting ipfstat -t output by source or +destination port. -block packets that fail to create state table entries +fix a bug in printing rules where interface names could not be printed, +even if they're in the rule structure. -correctly handle all return values from ip_natout() when fastrouting +fix BSD/kupgrade to correctly change ipfilter lkm Makefile for FreeBSD -ipmon was not correctly calculating the length of the IPv6 packet (excluded -ipv6 header length) +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) -3.4.34 20/4/2004 - Released +turn off function inlining for freebsd 5.3+ -correct the ICMP packet checksum fixing up when processing ICMP errors for NAT +UDP doesn't pullup enough data which can sometimes cause a panic. +Fix other protocols, as required, where a similar problem may exist. -various changes to ipsend for sending packets with ipv4 options +overhaul the timeout queue management, especially that for user defined queues +which are now only freed in an orderly manner. -look for ipmon's pidfile in /var/run and /etc/opt/ipf in Solaris' init script +4.1.7 - Released 13 March 2005 -only allow non-fragmented packets to influence whether or not a logged -packet is the same as the one logged before. +Using the GRE call field is almost impossible because it is unbalanced and +both call fields are not present in each v1 header. -make "ipfstat -f" output more informative +Fix a problem where it was possible to load duplicate rules into ipf -compatibility for openbsd byte order changes to ip_off/ip_len +patch from John Wehle to address problems with fastroute on solaris -disallow "freebsd" as a make target (encourages people to do the wrong thing) +Copying data out for ipf -z failed because it tried to copy out to an address +that is a kernel pointer in user space. -3.4.33 15/12/2003 - Released +add "ip" timeout for both NAT & state that's for non-TCP/UDP/ICMP -pass on messages moving through ipfilter when it is unloading itself on Solaris +synch up with NetBSD's changes -add disabling of auto-detach when the module attaches on Solaris +fix problems parsing long lines of text in the ftp proxy where they would not +be parsed properly and stop the session from working -compatibility patches for 'struct ifnet' changes on FreeBSD +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. -implement a maximum for the number of entries in the NAT table (NAT_TABLE_MAX -and ipf_nattable_max) +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. -fix ipfstat -A +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. -frsynclist() wasn't paying attention to all the places where interface -names are, like it should. +Linux requires that the checksums in the IP header get adjusted -fix where packet header pointers are pointing to after doing an ipf_pullup +only resolve unknown interfaces in fr_stinsert, and nuke all interface pointers +in SIOCSTPUT to prevent bad data being loaded from userspace. -fix comparing ICMP packets with established TCP state where only 8 bytes -of header are returned in the ICMP error. +make the byte counting for state correct (was counting data from ICMP packet +twice) -3.4.32 18/6/2003 - Released +print out the keyword "frag-body" if the flag is set. -fix up the behaviour of ipfs +fix ipfs loading/restoring NAT sessions -make parsing errors in ipf/ipnat return an error rather than return -indicating success. +patch from Frank to correctly format IP addresses in ipfstat -t output -window scaling patch +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. -make ipfstat work as a set{g,u}id thing - gave up privs before opening -/dev/ipl +4.1.6 - Released 19 February 2005 -checksum adjustment corrections for ICMP & NAT +add a new timeout number to NAT (fr_defnatipage) that is used for all +non-TCP/UDP/ICMP protocols - default 60 seconds. -attempt to always get an mbuf full of data through pullup if possible +buffer leak with bad nat - David Gueluy -Fix bug with NAT and fragments causing system to crash +fix memory leak with state entries created by proxies -Add patches for OpenBSD 3.3 +eliminate copying too much data into a scan buffer -stop LKM locking up the machine on modern NetBSD(?) +allow a trailing protocol name for map rules as well as rdr ones -allow timeouts in NAT rules to over-ride fr_defnatage if LARGE_NAT is defined +fix bug in parsing of <= and > for NAT rules (two were crossed over) -Locking patches for IRIX 6.5 from SGI. - -fix bug in synchronising state sessions where all interfaces were invalidated +FreeBSD's iplwrite hasn't kept pace with iplread's prototype -fix bug in openbsd 3.2 bridge diffs +expand documention on the karma of using "auto" in ipnat map rules -fix bug parsing port comparisons in proxy rules +add matching on IP protocol to ipnat map rules -3.4.31 7/12/2002 - Released +allow ippool definitions to contain no addresses to start with -Solaris 10 compatibility +Linux NAT needs to modify the IP header checksum as it gets called after it +has been computed by IP. -fix linking into pfil in NetBSD +UDP was missing a pullup for packet header information before examining +the header -fix IRIX 6.2 compatibility +4.1.5 - Released 9 January 2005 -add code to check consistency of fr_checkp/fr_check on non-Solaris +all rules were being converted into "dup-to" rules in the kernel -OpenBSD: missing patches for ip6_output.c on OpenBSD 3.2, - make LKM work for 3.2 (OpenBSD LKMs now match NetBSD) +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. -3.4.30 26/11/2002 - Released +response to CWDs +revert ip_off back to network byte order in the ICMP error packet that +gets generated. -attempt to detect using GNU make and abort if so +4.1.4 - Released 9 January 2005 -OpenBSD 3.2 patches from Stefan Hermes von GMX +force NAT rules to only match ipv4 NAT rules (which all are, currently, +by default) -add MSS clamping code from NetBSD +include state synchronisation fixes from Frank Volf -correctly display ipv6 output with ipfstat for (accounting) rules +make the maximum log size for internally buffered log entries accessible +via "ipf -T" -fix problems with ioctl handling for /dev/ipauth +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. -set SYN bit in rcmd fake packet to create back channel +tidy up sending ICMP error messages - some bad inputs could result in +data not being freed and/or no error returned. -make libpcap reader capable of determining in/out (not in libpcap file) -and add more DLT types +make the maximum size of the log buffer run-time tunable -do not allow redirects to localhost for Solaris in NAT parser +fix bug in parsing TCP header when looking for MSS option that could make +the system hang -allow return-rst with auth rules +change pool lookups that fail to find a match to return "no match" +rather than fail. -man page corrections +add run-time tunable debugging for proxy support code and FTP proxy. -fix for handling ipv6 icmp errors +fix state table updates for entries where the first packet as an ICMPv6 +multicast message -fix up ipfs command line option processing +fix hang when flushing state for v4/v6 and other (v6/v4) entries are present +too -only allow processing a ftp 227 response following a PASV command +attaching filtering to ipv6 pfil hook wasn't present for solaris -NetBSD: use poll() and adapt to new cdevsw mechanism +don't allow rules with "keep state" and "with oow" -make flushing for just ipv6 things work +move a bunch of userland only code from fil.c to ip_fil.c -3.4.29 28/8/2002 - Released +make fr_coalesce() more resiliant to bad input, just returning an error +instead of crashing, making calling it easier in many places -Make substantial changes to the FTP proxy to improve reliability, security -and functionality. +When m_pulldown doesn't return NULL, it doesn't necessarily return a pointer +to the same mbuf passed in as the first arg. -don't send ICMP errors/TCP RST's in response to blocked proxy packets +remove fr_unreach and use ENETUNREACH by default. -fix potential memory leaks when unloading ipfilter from kernel +printing out of tag data in ipf rules doesn't match input syntax -fix bug in SIOCGNATL handler that did not preserve the expected -byte order from earlier versions in the port number +ipftest(1) man page update -set do not fragment flag in generated packets according to system flags, -where available. +ipfs command line option parsing still rejects some valid syntaxes -preserve filter rule number and group number in state structure +SIGHUP handling by ipmon was not as safe as it could be -fix bug in ipmon printing of p/P/b/B +fix various parsing regressions, including "", "tcpudp", ordering +of "keep" options -make some changes to the kmem.c code for IRIX compatibility +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) -add code to specifically handle ip.tun* interfaces on Solaris +patches for return-rst and return-icmp from Attila Fueloep +(lichtscheu@gesindel.org) -3.4.28 6/6/2002 - Released +4.1.3 - Released 18 July 2004 -Fix for H.323 proxy to work on little endian boxes +do some more fine tuning on NAT checksum adjustments -IRIX: Update installation documentation - add route lock patch +correct IP address byte order in proxy setup for ipsec/pptp -allow use of groups > 65535 +man page updates -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 numerous problems with ipfs operation -fix the FTP proxy so that checks for TCP sequence numbers outside the -normal offset due to data changes use absolute numbers +complete new syntax for ipmon.conf in its parser and update the sample file -make it possible to remove rules in ipftest +assign error value consistantly in fastroute code -Update installing onto OpenBSD and split into two directories: -OpenBSD-2 and OpenBSD-3 +rewrite allocation of mbufs in send_reset/send_icmp_err to better use +mbuf clusters and size calculations -fix error in printout out the protocol in NAT rules +resolve problem with linux panic'ing because the wrong flag was being +passed to skb_clone/skb_alloc -always unlock ipfilter if locking fails half way through in ipfs +enable use of shared/exclusive locks on freebsd5 and above -fix problems with TCP window scaling +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 -update of man pages for ipnat(4) and ipftest(1) +replace lots of COPYIN/COPYOUT with BCOPYIN/BCOPYOUT where the data is +going to be on the stack and not in userland -3.4.27 28/04/2002 - Released +packet buffer pointers were not refreshed & used properly in fr_check() -fix calculation of 2's complmenent 16 bit checksum for user space +include extra bits for OpenBSD 3.4 & 3.5. -add mbuflen() to usespace compiles. +fix ipf/ipnat parsing regression problems with v3.4 -add more #ifdef complexity for platform portability +4.1.2 - RELEASED - 27 May 2004 -add OpenBSD 3.1 diffs +add state top for ipv6 -3.4.26 25/04/2002 - Released +fix numerous parsing regressions -fix parsing and printing of NAT rules with regression tests. +change sample proxies to use SIOCGNATL with the new API -add code to adjust TCP checksums inside ICMP errors where present and as -required for NAT. +allow macro names to contain underscores (_) -fix documentation problems in instal documents +split the parser into a collection of dictionaries so that keywords do +not interfere with resolving hostnames and portnames -fix locking problem with auth code on Solaris +fix ipfrule LKM loading on freebsd -fix use of version macros for FreeBSD and make the use of __FreeBSD_version -override previous hacks except when not present +support mapping a fixed range of ports to a single port -fix the macros defined for SIOCAUTHR and SIOCAUTHW +fix timeout queue use by proxies with private queues -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) +handle space-led ftp server replies properly -use the ip_ttl ndd parameter on Solaris to fill in ip_ttl for packets -generated by IPFilter +fix timeout queue management -fix comparing state information to delete state table entries +fix fastroute, generation of RST & ICMP packets and operation with to/fastroute -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 +resolve further linux compatibility problems -be stricter about what packets match a TCP state table entry if its creation -was triggered by a SYN packet. +replace the use of COPYIN with BCOPYIN for platforms that provide ioctl +args on the stack -add patches to handle TCP window scaling +allow flushing of ipv6 rules independant of ipv4 rules -don't update TCP state table entries if the packet is not considered to be -part of the connection +correct internal ipv6 checksum calculations -ipfs wasn't allowing -i command line option in getopt +if a 'keep state' rule fails to create state, block the packet rather +than let it through -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 +correct all checksums in regression tests and correct NAT code to adjust +checksums correctly. -change building in Makefiles to create links to the application in $(TOP) -at the end of "build" rather than when each is created. +fix ipfs -R/-W -update BSD/kupgrade for FreeBSD +4.1.1 - RELEASED - 24 March 2004 -l4check wasn't properly closing things when a connection fails +allow new connections with the same port numbers as an existing one +in the state table if the creating packet is a SYN -man page updates for ipmon(8) and ipnat(5) +timeout values have drifted, incorrectly, from what they were in 3.4 -more regression tests added. +FreeBSD - compatibility changes for 5.2 -3.4.25 13/03/2002 - 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" -retain rule # in state information +fr_cksum() returned the wrong answer for ICMP -log the direction of a packet so ipmon gets it right rather than incorrectly -deriving it from the rule flags +Linux: +- get return-rst and return-icmp working +- treat the interface name the same as if_xname on BSD -add #ifdef for IPFILTER_LOGSIZE (put options IPFILTER_LOGSIZE=16384 in BSD -kernel config files to increase that buffer size) +adjust expectations for TCP urgent bits based on observed traffic in the +wild -recognise return-* rules differently to block in ipftest +openbsd3.4 has ip_len/ip_off in network byte order when ipfilter is called -fix bug in ipmon output for solaris +fix flushing of hash pool gorups (ippool -F) as well as displaying them +(ippool -l) -add regression testing for skip rules, logging and using head/group +passing of pointers to interface structures wrong for HP-UX/Solaris with +return-* rules. -fix output of ipmon: was displaying large unsigned ints rather than -1 -when no rules matched. +Make the solaris boot script able to run on 2.5.1 -make logging code compile into ipftest and add -l command line option to -dump binary log file (read with ipmon -f) when it finishes. +ippool related files missing from Solaris packages -protect rule # and group # from interference when checking accounting rules +The name /dev/ippool should be /dev/iplookup -add regression testing for log output (text) from ipmon. +add regression testing for parsing long interface names in nat rules, +along with mssclamp and tags. Also add test for mssclamp operation. -document -b command line option for ipmon - -fix double-quick in Solaris startup script +ttl displayed for "ipfstat -t" is wrong because ttl is not computed. -3.4.24 01/03/2002 - Released +parse logical interface names (Sun) -fix how files are installed on SunOS5 +unloading LKMs was only working if they were enabled. -fix some minor problems in SunOS5 ipfboot script +sync'ing up NAT sessions when NICs change should cause NAT rules to +re-lookup name->pointer mappings -by default, compile all OpenBSD tools in 3.0 for IPv6 +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. -fix NULL-pointer dereference in NAT code +pool stats wrong: ippoolstate used where ipoolstat should be, hash table + statistics not reported at all -make a better attempt at replacing the appropriate binaries on BSD systems +fr_running not set correctly for OpenBSD when compiled into the kernel -always print IPv6 icmp-types as a number +Allow SIOCGETFF while disabled -impose some rules about what "skip" can be used with +Fix mssclamp with NAT (pasing and printing of the word, plus wrong bytes +altered. How do you say "untested" ?) -fix parsing problems with "keep state" and "keep state-age" +4.1 - RELEASED - 12 February 2004 -Try to read as much data as is in the log device in ipmon +4.0-BETA1 20 August 2003 -remove some redundant checks when searching for rdr/nat rules +support 0/32 and 0/0 on the RHS in redirect rules -fix bug in handling of ACCT with FTP proxy +where LHS and RHS netmasks are the same size for redirect, do 1:1 mapping +for bimap rules. -increase array size for interface names, using LIFNAMSIZ +allow NAT rule to match 'all' interfaces with * as interface name -include H.323 proxy from QNX +do mapping of ICMP sequence id#'s in pings -3.4.23 16/01/2002 - Released +allow default age for NAT entries to be set per NAT rule -Include patches to install IPFilter into OpenBSD 3.0, both for just kernel -compiles and complete system builds. +provide round robin selection of destination addresses for redirect -Fix bug in automatic flushing of state table which would cause it to hang -in an infinite loop bug introduced in 3.4.20. +ipmon can load a configuration file with instructions on actions +to take when a matching log entry is received -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. +now requires pfil to work on Solaris & HP-UX -Only support ICMPv6 with IPv6. +supports mapping outbound connections to a specific address/port -Move ipnat.1 to ipnat.8 +support toggling of logging per ipfilter 'device' -Enhance ipmon to print textual ICMP[v6] types and subtypes where possible. +use queues to expire data rather than lists -Make it possible to do IPv6 regression testing with ipftest. +add MSN RPC proxy -Use kvm library for kmem access, rather than trying to do it manually with -open/lseek/read. +add IRC proxy -Fix diffs for ip_input.c on BSDOS so it doesn't crash with fastroute. +support rules with dynamic ip addresses -Remove Berkeley advertising licence clause. Reference: -ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change +add ability to define a pool of addresses & networks which can then +be placed in a single rule -Add more regression tests: ICMPv6 neighbour discovery, ICMP time exceeded -and fragmentation required. +support passing entire packet back to user program for authentication -Fix ipfboot script on Solaris to deal with no nameservers or no route to -them in a clean manner. +support master/slave for state information sharing -Support per-rule set timeouts for non-TCP NAT and state +reorganise generic code into a lib directory and make libipf.a -Add netbios proxy +user programs enforce version matching with the kernel -Add ICMPv6 stateful checking, including handling multicast destination -addresses for neighbour discovery. +supports window scaling if seen at TCP session setup -Fix problems with internals of ICMP messages for MTU discovery and -unreachables not being correctly adjust on little endian boxes. +generates C code from filter rules to compile in or load as native +machine code. -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. +supports loading rules comprised of BPF bytecode statements -Fix ipfstat and ipnat for working on crash dumps. +HP-UX 11 port completed -Don't let USE_INET6 stay defined for SunOS4 +and packets-per-second filtering -Count things we see for each interface on solaris. +add numerical tags to rules for filtering and display in ipmon output -Include 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 :" - -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. - -add FI_IGNOREPKT and don't count so marked packets when doing stats or -state/nat. - -extend the interface name saved to log output - -make proxies capable of extending the matching done on a packet with a -particular nat session - -change interfaces inside NAT & state code to accomodate redesign to allow -IPsec proxy to work. - -fix bug when free'ing loaded rules that results in a memory leak -(only an issue with "ipf -rf -", not flush) - -make ipftest capable of loading > 1 file or rules, making it now possible -to load both NAT & filter rules - -fix hex input for ipftest to allow interface name & direction to work - -show ipsec proxy details in ipnat output - -if OPT_HEX is set in opts, print a packet out as hex - -don't modify b_next or preseve it or preserve b_prev for solaris - -fix up kinstall scripts to install all the files everywhere they need to - -fix overflowing of bits in ip_off inside iptest - -make userauth and proxy in samples directory compile - -fix minimum size when doing a pullup for ESP & ICMPv6 - -3.4.21 24/10/2001 - Released - -include ipsec proxy - -make state work for non-tcp/udp/icmp in a very simple way - -include diffs for ipv6 firewall on openbsd-2.9 - -add compatibility filter wrapper for NetBSD-current - -fix command line option problems with ipfs - -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 - -fix bug with sending resets/icmp errors where the pointer to the data -section of the packet was not being set (BSD only) - -split out validating ftp commands and responses into different halves, -one for each of server & client. - -do not compile in STATETOP support for specific architectures - -fix INSTALL.FreeBSD to no longer provide directions and properly direct -people to the right file for the right version of FreeBSD. - -3.4.20 24/07/2001 - Released - -adjust NAT hashing to give a better spread across the table - -show icmp code/type names in output, where known - -fix bug in altering cached interface names in state when resync'ing - -fix bug in real audio proxy that caused crashs - -fix compiling using sunos4 cc - -patch from casper to address weird exit problem for ipstat in top mode - -patch from Greg Woods to produce names for icmp types/unreach codes, -where they are known - -fix bug where ipfr_fastroute() would use a mblk and it would also get -freed later. - -don't match fragments which would cause 64k length to be exceeded - -ftp proxy fix for port numbers being setup for pasv ftp with state/nat - -change hashing for NAT to include both IP#'s and ports. - -Solaris fixes for IPv6 - -fix compiling iplang bits, under Solaris, for ipsend - -3.4.19 29/06/2001 - Released - -fix to support suspend/resume on solaris8 as well as ipv6 - -include group/group-head in match of filter rules - -fix endian problem reading snoop files - -make all licence comments point to the one place - -fix ftp proxy to only advance state if a reply is received in response to -a recognised command - -3.4.18 05/06/2001 - Released - -fix up parsing of "from ! host" where '!' is separate - -disable hardware checksums for NetBSD - -put ipftest temporary files in . rather than /tmp - -modify ftp proxy to be more intelligent about moving between states -and recognise new authentication commands - -allow state/nat table sizes to be externally influenced - -print out host mapping table for NAT with ipnat -l - -fix handling of hardware checksum'ing on Solaris - -fixup makefiles for Solaris - -update regression tests - -fix surrender of SPL's for failure cases - -include patches for OpenBSD's new timeout mechanism - -default ipl_unreach to ICMP_UNREACH_FILTER_PROHIB if defined, else make it -ICMP_UNREACH_FILTER - -fix up handling of packets matching auth rules and interaction with state - -add -q command line option to ipfstat on Solaris to list bound interfaces - -add command line option to ipfstat/ipnat to select different core image - -don't use ncurses on Solaris for STATETOP - -fix includes to get FreeBSD version - -do not byte swap ip_id - -fix handling success for packets matching the auth rule - -don't double-count short packets - -add ICMP router discovery message size recognition - -fix packet length calculation for IPv6 - -set CPUDIR when for install-sunos5 make target - -SUNWspro -xF causes Solaris 2.5.1 kernel to crash - -3.4.17 06/04/2001 - Released - -fix fragment#0 handling bug where they could get in via cache information -created by state table entries - -use ire_walk to look for ire cache entries with link layer headers cached - -deal with bad SPL assumptions for log reading on BSD - -fix ftp proxy to allow logins with passwords - -some auth rule patches, fixing byte endian problems and returning as an error - -support LOG_SECURITY, where available, in ipmon - -don't return an error for packets which match auth rules - -introduce fr_icmpacktimeout to timeout entries once an ICMP reply has -been seen separately to when created - -3.4.16 15/01/2001 - Released - -fix race condition in flushing of state entries that are timing out - -Add TCP ECN patches - -log all NAT entries created, not just those via rules - -3.4.15 17/12/2000 - Released - -add minimum ttl filtering (to be replaced later by return-icmp-as-dest -for all ICMP packets matching state entries). - -fix NAT'ing of fragments - -fix sanity checks for ICMPV6 - -fix up compiling on IRIX 6.2 with IDF/IDL installed - -3.4.14 02/11/2000 - Released - -cause flushing NAT table to generate log records the same as state flush -does. - -fix ftp proxy port/pasv - -fix problem where nat_{in,out}lookup() would release a write lock when it -didn't need to. - -add check for ipf6.conf in Solaris ipfboot - -3.4.13 28/10/2000 - Released - -fix introduced bug with ICMP packets being rejected when valid - -fix bug with proxy's that don't set fin_dlen correctly when calling -fr_addstate() - -3.4.12 26/10/2000 - Released - -fix installing into FreeBSD-4.1 - -fix FTP proxy bug where it'd hang and make NAT slightly more efficient - -fix general compiling errors/warnings on various platforms - -don't access ICMP data fields that aren't there - -3.4.11 09/10/2000 - Released - -return NULL for IPv6 access control lists if it is disabled rather than -random garbage. - -fix for getting protocol & packet length for IPv6 packets for pullup. - -update plog script from version 0.8 to version 0.10 - -patch from Frank Volf adding fix_datacksum() to NAT code, enhancing the -capabilities for "fixing" checksums. - -3.4.10 03/09/2000 - Released - -merge patch from Frank Volf for ICMP nat handling of TCP/UDP data `errors' - -getline() adjusts linenum now - -add tcphalfclosed timeout - -fill in icmp_nextmtu field if it is defined on the platform - -RST generation fix from guido - -force 32bit compile for gcc on solaris if it can't generate 64bit code - -encase logging when fr_chksrc == 2 in #ifdef IPFILTER_LOG - -fix up line wrap problems in plog script - -fix ICMP packet handling to not drop valid ICMP errors - -freebsd 5.0 compat changes - -3.4.9 08/08/2000 - Released - -implement new aging mechanism in fr_tcp_age() - -fix icmp state checking bug - -revamp buildsunos script and build both sparcv7/sparcv9 for Solaris -if on an Ultra with a 64bit system & compiler (Caseper Dik) - -open ipfilter device read only if we know we can - -print out better information for ICMP packets in ipmon - -move checking for source spoofed packets to a point where we can generate -logs of them - -return EFAULT from ircopyptr/iwcopyptr - -don't do ioctl(SIOCGETFS) for auth stats - -fix up freeing mbufs for post-4.3BSD - -fix returning of inc from ftp proxy - -fix bugs with ipfs -R/-W (Caseper Dik) - -3.4.8 19/07/2000 - Released - -create fake opt_inet6.h for FreeBSD-4 compile as LKM - -add #ifdef's for KLD_MODULE sanity - -NAT fastroute'd packets which come out of return-* - -fix upper/lower case crap in ftp proxy and get seq# checking fixed up. - -3.4.7 08/07/2000 - Released - -make "ipf -y" lookup NAT if's which are unknown - -prepend line numbers to ioctl error messages in ipf/ipnat - -don't apply patches to FreeBSD twice - -allow for ip_len to be on an unaligned boundary early on in fr_precheck - -fix printing of icmp code when it is 0 - -correct printing of port numbers in map rules with from/to - -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. - -3.4.6 11/06/2000 - Released - -add extra regression tests for new nat functionality - -place restrictions on using '!' in map/rdr rules - -fix up solaris compile problems - -3.4.5 10/06/2000 - Released - -mention -sl in ipfstat.8 - -fix/support '!' in from/to rules (rdr) for NAT - -add from/to support to rdr NAT rules - -don't send ICMP errors in response to ICMP errors - -fix sunos5 compilation for "ipfstat-top" and cleanup ipfboot - -input accounting list used for both outbound and inbound packets - -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/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 should be supplied that defines the additional + * DLT_* codes appropriately for that platform (the BSDs, for example, + * should not just pick up this version of "bpf.h"; they should also define + * the additional DLT_* codes used by their kernels, as well as the values + * defined here - and, if the values they use for particular DLT_ types + * differ from those here, they should use their values, not the ones + * here). + */ +#define DLT_NULL 0 /* no link-layer encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* IEEE 802 Networks */ +#define DLT_ARCNET 7 /* ARCNET */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are values from the traditional libpcap "bpf.h". + * Ports of this to particular platforms should replace these definitions + * with the ones appropriate to that platform, if the values are + * different on that platform. + */ +#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ +#define DLT_RAW 12 /* raw IP */ + +/* + * These are values from BSD/OS's "bpf.h". + * These are not the same as the values from the traditional libpcap + * "bpf.h"; however, these values shouldn't be generated by any + * OS other than BSD/OS, so the correct values to use here are the + * BSD/OS values. + * + * Platforms that have already assigned these values to other + * DLT_ codes, however, should give these codes the values + * from that platform, so that programs that use these codes will + * continue to compile - even though they won't correctly read + * files of these types. + */ +#ifdef __NetBSD__ +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer types corresponding to DLT_ types that differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * Values between 106 and 107 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ new types. + */ + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * OpenBSD defines it as 12, but that collides with DLT_RAW, so we + * define it as 108 here. If OpenBSD picks up this file, it should + * define DLT_LOOP as 12 in its version, as per the comment above - + * and should not use 108 as a DLT_ value. + */ +#define DLT_LOOP 108 + +/* + * Values between 109 and 112 are used in capture file headers as + * link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * Reserved for use in capture-file headers as a link-layer type + * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, + * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it + * in capture-file headers. + */ +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * Reserved for 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Reserved for Siemens HiPath HDLC. + */ +#define DLT_HHDLC 121 + +/* + * Reserved for RFC 2625 IP-over-Fibre Channel, as per a request from + * Don Lee . + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * The instruction encodings. + */ +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +#define BPF_TXA 0x80 + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_int32 k; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL)) +/* + * Systems based on non-BSD kernels don't have ifnet's (or they don't mean + * anything if it is in ) and won't work like this. + */ +# if __STDC__ +extern void bpf_tap(struct ifnet *, u_char *, u_int); +extern void bpf_mtap(struct ifnet *, struct mbuf *); +extern void bpfattach(struct ifnet *, u_int, u_int); +extern void bpfilterattach(int); +# else +extern void bpf_tap(); +extern void bpf_mtap(); +extern void bpfattach(); +extern void bpfilterattach(); +# endif /* __STDC__ */ +#endif /* BSD && (_KERNEL || KERNEL) */ +#if __STDC__ || defined(__cplusplus) +extern int bpf_validate(struct bpf_insn *, int); +extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); +#else +extern int bpf_validate(); +extern u_int bpf_filter(); +#endif + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/ipfilter/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 +#include +#include +#include + +#include +#include + +#include "ip_compat.h" +#include "bpf-ipf.h" + + +#if (defined(__hpux) || SOLARIS) && (defined(_KERNEL) || defined(KERNEL)) +# include +# include +#endif + +#include "pcap-ipf.h" + +#if !defined(KERNEL) && !defined(_KERNEL) +#include +#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/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/ip_fil_freebsd.c b/contrib/ipfilter/ip_fil_freebsd.c new file mode 100644 index 000000000000..3b36b93117a8 --- /dev/null +++ b/contrib/ipfilter/ip_fil_freebsd.c @@ -0,0 +1,1692 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ip_fil_freebsd.c,v 2.53.2.25 2005/02/01 03:15:56 darrenr Exp"; +#endif + +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \ + !defined(KLD_MODULE) && !defined(IPFILTER_LKM) +# include "opt_inet6.h" +#endif +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 440000) && \ + !defined(KLD_MODULE) && !defined(IPFILTER_LKM) +# include "opt_random_ip_id.h" +#endif +#include +#if defined(__FreeBSD__) && !defined(__FreeBSD_version) +# if defined(IPFILTER_LKM) +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 +# include +# endif +# endif +# endif +#endif +#include +#include +#include +#if __FreeBSD_version >= 220000 +# include +# include +#else +# include +#endif +#include +#include +#if (__FreeBSD_version >= 300000) +# include +#else +# include +#endif +#if !defined(__hpux) +# include +#endif +#include +#include + +#include +#if __FreeBSD_version >= 300000 +# include +# if !defined(IPFILTER_LKM) +# include "opt_ipfilter.h" +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#if defined(__osf__) +# include +#endif +#include +#include +#include +#ifndef _KERNEL +# include "netinet/ipf.h" +#endif +#include "netinet/ip_compat.h" +#ifdef USE_INET6 +# include +#endif +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_frag.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "netinet/ip_auth.h" +#ifdef IPFILTER_SYNC +#include "netinet/ip_sync.h" +#endif +#ifdef IPFILTER_SCAN +#include "netinet/ip_scan.h" +#endif +#include "netinet/ip_pool.h" +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) +# include +#endif +#include +#ifdef CSUM_DATA_VALID +#include +#endif +extern int ip_optcopy __P((struct ip *, struct ip *)); + +#if (__FreeBSD_version > 460000) +extern int path_mtu_discovery; +#endif + +# ifdef IPFILTER_M_IPFILTER +MALLOC_DEFINE(M_IPFILTER, "IP Filter", "IP Filter packet filter data structures"); +# endif + + +#if !defined(__osf__) +extern struct protosw inetsw[]; +#endif + +static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **)); +static int fr_send_ip __P((fr_info_t *, mb_t *, mb_t **)); +# ifdef USE_MUTEXES +ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert; +ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; +ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag; +ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; +# endif +int ipf_locks_done = 0; + +#if (__FreeBSD_version >= 300000) +struct callout_handle fr_slowtimer_ch; +#endif + +#if (__FreeBSD_version >= 500011) +# include +# if defined(NETBSD_PF) +# include +# include +/* + * We provide the fr_checkp name just to minimize changes later. + */ +int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp)); +# endif /* NETBSD_PF */ +#endif /* __FreeBSD_version >= 500011 */ + + +#if (__FreeBSD_version >= 501108) && defined(_KERNEL) + +static int +fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +{ + struct ip *ip = mtod(*mp, struct ip *); + return fr_check(ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), mp); +} + +# ifdef USE_INET6 +# include + +static int +fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) +{ + return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr), + ifp, (dir == PFIL_OUT), mp)); +} +# endif +#endif /* __FreeBSD_version >= 501108 */ +#if defined(IPFILTER_LKM) +int iplidentify(s) +char *s; +{ + if (strcmp(s, "ipl") == 0) + return 1; + return 0; +} +#endif /* IPFILTER_LKM */ + + +int iplattach() +{ +#ifdef USE_SPL + int s; +#endif +#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) + int error = 0; +# if __FreeBSD_version >= 501108 + struct pfil_head *ph_inet; +# ifdef USE_INET6 + struct pfil_head *ph_inet6; +# endif +# endif +#endif + + SPL_NET(s); + if (fr_running > 0) { + SPL_X(s); + return EBUSY; + } + + MUTEX_INIT(&ipf_rw, "ipf rw mutex"); + RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); + MUTEX_INIT(&ipf_timeoutlock, "ipf timeout queue mutex"); + RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); + RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); + ipf_locks_done = 1; + + if (fr_initialise() < 0) { + SPL_X(s); + return EIO; + } + + +# ifdef NETBSD_PF +# if __FreeBSD_version >= 500011 +# if __FreeBSD_version >= 501108 + ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); +# ifdef USE_INET6 + ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); +# endif + if (ph_inet == NULL +# ifdef USE_INET6 + && ph_inet6 == NULL +# endif + ) + return ENODEV; + + if (ph_inet != NULL) + error = pfil_add_hook((void *)fr_check_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet); + else + error = 0; +# else + error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, + &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); +# endif + if (error) { +# ifdef USE_INET6 + goto pfil_error; +# else + fr_deinitialise(); + SPL_X(s); + return error; +# endif + } +# else + pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT); +# endif +# ifdef USE_INET6 +# if __FreeBSD_version >= 501108 + if (ph_inet6 != NULL) + error = pfil_add_hook((void *)fr_check_wrapper6, NULL, + PFIL_IN|PFIL_OUT, ph_inet6); + else + error = 0; + if (error) { + pfil_remove_hook((void *)fr_check_wrapper6, NULL, + PFIL_IN|PFIL_OUT, ph_inet6); +# else + error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, + &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); + if (error) { + pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, + &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); +# endif +pfil_error: + fr_deinitialise(); + SPL_X(s); + return error; + } +# endif +# endif + if (fr_checkp != fr_check) { + fr_savep = fr_checkp; + fr_checkp = fr_check; + } + + bzero((char *)frcache, sizeof(frcache)); + fr_running = 1; + + if (fr_control_forwarding & 1) + ipforwarding = 1; + + SPL_X(s); +#if (__FreeBSD_version >= 300000) + fr_slowtimer_ch = timeout(fr_slowtimer, NULL, + (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); +#else + timeout(fr_slowtimer, NULL, (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); +#endif + return 0; +} + + +/* + * Disable the filter by removing the hooks from the IP input/output + * stream. + */ +int ipldetach() +{ +#ifdef USE_SPL + int s; +#endif +#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) + int error = 0; +# if __FreeBSD_version >= 501108 + struct pfil_head *ph_inet; +# ifdef USE_INET6 + struct pfil_head *ph_inet6; +# endif +# endif +#endif + + if (fr_control_forwarding & 2) + ipforwarding = 0; + + SPL_NET(s); + +#if (__FreeBSD_version >= 300000) + if (fr_slowtimer_ch.callout != NULL) + untimeout(fr_slowtimer, NULL, fr_slowtimer_ch); + bzero(&fr_slowtimer_ch, sizeof(fr_slowtimer_ch)); +#else + untimeout(fr_slowtimer, NULL); +#endif /* FreeBSD */ + +#ifndef NETBSD_PF + if (fr_checkp != NULL) + fr_checkp = fr_savep; + fr_savep = NULL; +#endif + +#ifdef NETBSD_PF +# if (__FreeBSD_version >= 500011) +# if (__FreeBSD_version >= 501108) + ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); + if (ph_inet != NULL) + error = pfil_remove_hook((void *)fr_check_wrapper, NULL, + PFIL_IN|PFIL_OUT, ph_inet); + else + error = 0; +# else + error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, + &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); +# endif + if (error) { + SPL_X(s); + return error; + } +# else + pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT); +# endif +# ifdef USE_INET6 +# if (__FreeBSD_version >= 501108) + ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); + if (ph_inet6 != NULL) + error = pfil_remove_hook((void *)fr_check_wrapper6, NULL, + PFIL_IN|PFIL_OUT, ph_inet6); + else + error = 0; +# else + error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, + &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); +# endif + if (error) { + SPL_X(s); + return error; + } +# endif +#endif + fr_deinitialise(); + + fr_running = -2; + + (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); + (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE); + + if (ipf_locks_done == 1) { + MUTEX_DESTROY(&ipf_timeoutlock); + MUTEX_DESTROY(&ipf_rw); + RW_DESTROY(&ipf_mutex); + RW_DESTROY(&ipf_ipidfrag); + RW_DESTROY(&ipf_global); + ipf_locks_done = 0; + } + + SPL_X(s); + + return 0; +} + + +/* + * Filter ioctl interface. + */ +int iplioctl(dev, cmd, data, mode +# if defined(_KERNEL) && ((BSD >= 199506) || (__FreeBSD_version >= 220000)) +, p) +# if (__FreeBSD_version >= 500024) +struct thread *p; +# else +struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +# else +) +# endif +#if defined(_KERNEL) && (__FreeBSD_version >= 502116) +struct cdev *dev; +#else +dev_t dev; +#endif +ioctlcmd_t cmd; +caddr_t data; +int mode; +{ +#ifdef USE_SPL + int s; +#endif + int error = 0, unit = 0, tmp; + friostat_t fio; + +#if (BSD >= 199306) && defined(_KERNEL) + if ((securelevel >= 2) && (mode & FWRITE)) + return EPERM; +#endif + + unit = GET_MINOR(dev); + if ((IPL_LOGMAX < unit) || (unit < 0)) + return ENXIO; + + if (fr_running <= 0) { + if (unit != IPL_LOGIPF) + return EIO; + if (cmd != SIOCIPFGETNEXT && cmd != SIOCIPFGET && + cmd != SIOCIPFSET && cmd != SIOCFRENB && + cmd != SIOCGETFS && cmd != SIOCGETFF) + return EIO; + } + + SPL_NET(s); + + error = fr_ioctlswitch(unit, data, cmd, mode); + if (error != -1) { + SPL_X(s); + return error; + } + error = 0; + + switch (cmd) + { + case FIONREAD : +#ifdef IPFILTER_LOG + BCOPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data, + sizeof(iplused[IPL_LOGIPF])); +#endif + break; + case SIOCFRENB : + if (!(mode & FWRITE)) + error = EPERM; + else { + BCOPYIN(data, &tmp, sizeof(tmp)); + if (tmp) { + if (fr_running > 0) + error = 0; + else + error = iplattach(); + if (error == 0) + fr_running = 1; + else + (void) ipldetach(); + } else { + error = ipldetach(); + if (error == 0) + fr_running = -1; + } + } + break; + case SIOCIPFSET : + if (!(mode & FWRITE)) { + error = EPERM; + break; + } + case SIOCIPFGETNEXT : + case SIOCIPFGET : + error = fr_ipftune(cmd, data); + break; + case SIOCSETFF : + if (!(mode & FWRITE)) + error = EPERM; + else + BCOPYIN(data, &fr_flags, sizeof(fr_flags)); + break; + case SIOCGETFF : + BCOPYOUT(&fr_flags, data, sizeof(fr_flags)); + break; + case SIOCFUNCL : + error = fr_resolvefunc(data); + break; + case SIOCINAFR : + case SIOCRMAFR : + case SIOCADAFR : + case SIOCZRLST : + if (!(mode & FWRITE)) + error = EPERM; + else + error = frrequest(unit, cmd, data, fr_active, 1); + break; + case SIOCINIFR : + case SIOCRMIFR : + case SIOCADIFR : + if (!(mode & FWRITE)) + error = EPERM; + else + error = frrequest(unit, cmd, data, 1 - fr_active, 1); + break; + case SIOCSWAPA : + if (!(mode & FWRITE)) + error = EPERM; + else { + bzero((char *)frcache, sizeof(frcache[0]) * 2); + *(u_int *)data = fr_active; + fr_active = 1 - fr_active; + } + break; + case SIOCGETFS : + fr_getstat(&fio); + error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); + break; + case SIOCFRZST : + if (!(mode & FWRITE)) + error = EPERM; + else + error = fr_zerostats(data); + break; + case SIOCIPFFL : + if (!(mode & FWRITE)) + error = EPERM; + else { + BCOPYIN(data, &tmp, sizeof(tmp)); + tmp = frflush(unit, 4, tmp); + BCOPYOUT(&tmp, data, sizeof(tmp)); + } + break; +#ifdef USE_INET6 + case SIOCIPFL6 : + if (!(mode & FWRITE)) + error = EPERM; + else { + BCOPYIN(data, &tmp, sizeof(tmp)); + tmp = frflush(unit, 6, tmp); + BCOPYOUT(&tmp, data, sizeof(tmp)); + } + break; +#endif + case SIOCSTLCK : + BCOPYIN(data, &tmp, sizeof(tmp)); + fr_state_lock = tmp; + fr_nat_lock = tmp; + fr_frag_lock = tmp; + fr_auth_lock = tmp; + break; +#ifdef IPFILTER_LOG + case SIOCIPFFB : + if (!(mode & FWRITE)) + error = EPERM; + else + *(int *)data = ipflog_clear(unit); + break; +#endif /* IPFILTER_LOG */ + case SIOCGFRST : + error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); + break; + case SIOCFRSYN : + if (!(mode & FWRITE)) + error = EPERM; + else { + frsync(NULL); + } + break; + default : + error = EINVAL; + break; + } + SPL_X(s); + return error; +} + + +#if 0 +void fr_forgetifp(ifp) +void *ifp; +{ + register frentry_t *f; + + WRITE_ENTER(&ipf_mutex); + for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; + for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; + for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; + for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; +#ifdef USE_INET6 + for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; + for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; + for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; + for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) + if (f->fr_ifa == ifp) + f->fr_ifa = (void *)-1; +#endif + RWLOCK_EXIT(&ipf_mutex); + fr_natsync(ifp); +} +#endif + + +/* + * routines below for saving IP headers to buffer + */ +int iplopen(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) && defined(_KERNEL) +, devtype, p) +int devtype; +# if (__FreeBSD_version >= 500024) +struct thread *p; +# else +struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if defined(_KERNEL) && (__FreeBSD_version >= 502116) +struct cdev *dev; +#else +dev_t dev; +#endif +int flags; +{ + u_int min = GET_MINOR(dev); + + if (IPL_LOGMAX < min) + min = ENXIO; + else + min = 0; + return min; +} + + +int iplclose(dev, flags +#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) && defined(_KERNEL) +, devtype, p) +int devtype; +# if (__FreeBSD_version >= 500024) +struct thread *p; +# else +struct proc *p; +# endif /* __FreeBSD_version >= 500024 */ +#else +) +#endif +#if defined(_KERNEL) && (__FreeBSD_version >= 502116) +struct cdev *dev; +#else +dev_t dev; +#endif +int flags; +{ + u_int min = GET_MINOR(dev); + + if (IPL_LOGMAX < min) + min = ENXIO; + else + min = 0; + return min; +} + +/* + * iplread/ipllog + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +int iplread(dev, uio, ioflag) +int ioflag; +#else +int iplread(dev, uio) +#endif +#if defined(_KERNEL) && (__FreeBSD_version >= 502116) +struct cdev *dev; +#else +dev_t dev; +#endif +register struct uio *uio; +{ + +# ifdef IPFILTER_SYNC + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipfsync_read(uio); +# endif + +#ifdef IPFILTER_LOG + return ipflog_read(GET_MINOR(dev), uio); +#else + return ENXIO; +#endif +} + + +/* + * iplwrite + * both of these must operate with at least splnet() lest they be + * called during packet processing and cause an inconsistancy to appear in + * the filter lists. + */ +#if (BSD >= 199306) +int iplwrite(dev, uio, ioflag) +int ioflag; +#else +int iplwrite(dev, uio) +#endif +#if defined(_KERNEL) && (__FreeBSD_version >= 502116) +struct cdev *dev; +#else +dev_t dev; +#endif +register struct uio *uio; +{ + +#ifdef IPFILTER_SYNC + if (GET_MINOR(dev) == IPL_LOGSYNC) + return ipfsync_write(uio); +#endif + return ENXIO; +} + + +/* + * fr_send_reset - this could conceivably be a call to tcp_respond(), but that + * requires a large amount of setting up and isn't any more efficient. + */ +int fr_send_reset(fin) +fr_info_t *fin; +{ + struct tcphdr *tcp, *tcp2; + int tlen = 0, hlen; + struct mbuf *m; +#ifdef USE_INET6 + ip6_t *ip6; +#endif + ip_t *ip; + + tcp = fin->fin_dp; + if (tcp->th_flags & TH_RST) + return -1; /* feedback loop */ + +#ifndef IPFILTER_CKSUM + if (fr_checkl4sum(fin) == -1) + return -1; +#endif + + tlen = fin->fin_dlen - (TCP_OFF(tcp) << 2) + + ((tcp->th_flags & TH_SYN) ? 1 : 0) + + ((tcp->th_flags & TH_FIN) ? 1 : 0); + +#ifdef USE_INET6 + hlen = (fin->fin_v == 6) ? sizeof(ip6_t) : sizeof(ip_t); +#else + hlen = sizeof(ip_t); +#endif +#ifdef MGETHDR + MGETHDR(m, M_DONTWAIT, MT_HEADER); +#else + MGET(m, M_DONTWAIT, MT_HEADER); +#endif + if (m == NULL) + return -1; + if (sizeof(*tcp2) + hlen > MLEN) { + MCLGET(m, M_DONTWAIT); + if ((m->m_flags & M_EXT) == 0) { + FREE_MB_T(m); + return -1; + } + } + + m->m_len = sizeof(*tcp2) + hlen; +#if (BSD >= 199103) + m->m_data += max_linkhdr; + m->m_pkthdr.len = m->m_len; + m->m_pkthdr.rcvif = (struct ifnet *)0; +#endif + ip = mtod(m, struct ip *); + bzero((char *)ip, hlen); +#ifdef USE_INET6 + ip6 = (ip6_t *)ip; +#endif + tcp2 = (struct tcphdr *)((char *)ip + hlen); + tcp2->th_sport = tcp->th_dport; + tcp2->th_dport = tcp->th_sport; + + if (tcp->th_flags & TH_ACK) { + tcp2->th_seq = tcp->th_ack; + tcp2->th_flags = TH_RST; + tcp2->th_ack = 0; + } else { + tcp2->th_seq = 0; + tcp2->th_ack = ntohl(tcp->th_seq); + tcp2->th_ack += tlen; + tcp2->th_ack = htonl(tcp2->th_ack); + tcp2->th_flags = TH_RST|TH_ACK; + } + TCP_X2_A(tcp2, 0); + TCP_OFF_A(tcp2, sizeof(*tcp2) >> 2); + tcp2->th_win = tcp->th_win; + tcp2->th_sum = 0; + tcp2->th_urp = 0; + +#ifdef USE_INET6 + if (fin->fin_v == 6) { + ip6->ip6_flow = ((ip6_t *)fin->fin_ip)->ip6_flow; + ip6->ip6_plen = htons(sizeof(struct tcphdr)); + ip6->ip6_nxt = IPPROTO_TCP; + ip6->ip6_hlim = 0; + ip6->ip6_src = fin->fin_dst6; + ip6->ip6_dst = fin->fin_src6; + tcp2->th_sum = in6_cksum(m, IPPROTO_TCP, + sizeof(*ip6), sizeof(*tcp2)); + return fr_send_ip(fin, m, &m); + } +#endif + ip->ip_p = IPPROTO_TCP; + ip->ip_len = htons(sizeof(struct tcphdr)); + ip->ip_src.s_addr = fin->fin_daddr; + ip->ip_dst.s_addr = fin->fin_saddr; + tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2)); + ip->ip_len = hlen + sizeof(*tcp2); + return fr_send_ip(fin, m, &m); +} + + +static int fr_send_ip(fin, m, mpp) +fr_info_t *fin; +mb_t *m, **mpp; +{ + fr_info_t fnew; + ip_t *ip, *oip; + int hlen; + + ip = mtod(m, ip_t *); + bzero((char *)&fnew, sizeof(fnew)); + + IP_V_A(ip, fin->fin_v); + switch (fin->fin_v) + { + case 4 : + fnew.fin_v = 4; + oip = fin->fin_ip; + IP_HL_A(ip, sizeof(*oip) >> 2); + ip->ip_tos = oip->ip_tos; + ip->ip_id = fin->fin_ip->ip_id; +#if (__FreeBSD_version > 460000) + ip->ip_off = path_mtu_discovery ? IP_DF : 0; +#else + ip->ip_off = 0; +#endif + ip->ip_ttl = ip_defttl; + ip->ip_sum = 0; + hlen = sizeof(*oip); + break; +#ifdef USE_INET6 + case 6 : + { + ip6_t *ip6 = (ip6_t *)ip; + + ip6->ip6_vfc = 0x60; + ip6->ip6_hlim = IPDEFTTL; + + fnew.fin_v = 6; + hlen = sizeof(*ip6); + break; + } +#endif + default : + return EINVAL; + } +#ifdef IPSEC + m->m_pkthdr.rcvif = NULL; +#endif + + fnew.fin_ifp = fin->fin_ifp; + fnew.fin_flx = FI_NOCKSUM; + fnew.fin_m = m; + fnew.fin_ip = ip; + fnew.fin_mp = mpp; + fnew.fin_hlen = hlen; + fnew.fin_dp = (char *)ip + hlen; + (void) fr_makefrip(hlen, ip, &fnew); + + return fr_fastroute(m, mpp, &fnew, NULL); +} + + +int fr_send_icmp_err(type, fin, dst) +int type; +fr_info_t *fin; +int dst; +{ + int err, hlen, xtra, iclen, ohlen, avail, code; + struct in_addr dst4; + struct icmp *icmp; + struct mbuf *m; + void *ifp; +#ifdef USE_INET6 + ip6_t *ip6; + struct in6_addr dst6; +#endif + ip_t *ip, *ip2; + + if ((type < 0) || (type > ICMP_MAXTYPE)) + return -1; + + code = fin->fin_icode; +#ifdef USE_INET6 + if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int))) + return -1; +#endif + +#ifndef IPFILTER_CKSUM + if (fr_checkl4sum(fin) == -1) + return -1; +#endif +#ifdef MGETHDR + MGETHDR(m, M_DONTWAIT, MT_HEADER); +#else + MGET(m, M_DONTWAIT, MT_HEADER); +#endif + if (m == NULL) + return -1; + avail = MHLEN; + + xtra = 0; + hlen = 0; + ohlen = 0; + ifp = fin->fin_ifp; + if (fin->fin_v == 4) { + if ((fin->fin_p == IPPROTO_ICMP) && + !(fin->fin_flx & FI_SHORT)) + switch (ntohs(fin->fin_data[0]) >> 8) + { + case ICMP_ECHO : + case ICMP_TSTAMP : + case ICMP_IREQ : + case ICMP_MASKREQ : + break; + default : + FREE_MB_T(m); + return 0; + } + + if (dst == 0) { + if (fr_ifpaddr(4, FRI_NORMAL, ifp, + &dst4, NULL) == -1) { + FREE_MB_T(m); + return -1; + } + } else + dst4.s_addr = fin->fin_daddr; + + hlen = sizeof(ip_t); + ohlen = fin->fin_hlen; + if (fin->fin_hlen < fin->fin_plen) + xtra = MIN(fin->fin_dlen, 8); + else + xtra = 0; + } + +#ifdef USE_INET6 + else if (fin->fin_v == 6) { + hlen = sizeof(ip6_t); + ohlen = sizeof(ip6_t); + type = icmptoicmp6types[type]; + if (type == ICMP6_DST_UNREACH) + code = icmptoicmp6unreach[code]; + + if (hlen + sizeof(*icmp) + max_linkhdr + + fin->fin_plen > avail) { + MCLGET(m, M_DONTWAIT); + if ((m->m_flags & M_EXT) == 0) { + FREE_MB_T(m); + return -1; + } + avail = MCLBYTES; + } + xtra = MIN(fin->fin_plen, + avail - hlen - sizeof(*icmp) - max_linkhdr); + if (dst == 0) { + if (fr_ifpaddr(6, FRI_NORMAL, ifp, + (struct in_addr *)&dst6, NULL) == -1) { + FREE_MB_T(m); + return -1; + } + } else + dst6 = fin->fin_dst6; + } +#endif + else { + FREE_MB_T(m); + return -1; + } + + iclen = hlen + sizeof(*icmp); + avail -= (max_linkhdr + iclen); + if (avail < 0) { + FREE_MB_T(m); + return -1; + } + if (xtra > avail) + xtra = avail; + iclen += xtra; + m->m_data += max_linkhdr; + m->m_pkthdr.rcvif = (struct ifnet *)0; + m->m_pkthdr.len = iclen; + m->m_len = iclen; + ip = mtod(m, ip_t *); + icmp = (struct icmp *)((char *)ip + hlen); + ip2 = (ip_t *)&icmp->icmp_ip; + + icmp->icmp_type = type; + icmp->icmp_code = fin->fin_icode; + icmp->icmp_cksum = 0; +#ifdef icmp_nextmtu + if (type == ICMP_UNREACH && + fin->fin_icode == ICMP_UNREACH_NEEDFRAG && ifp) + icmp->icmp_nextmtu = htons(((struct ifnet *)ifp)->if_mtu); +#endif + + bcopy((char *)fin->fin_ip, (char *)ip2, ohlen); + +#ifdef USE_INET6 + ip6 = (ip6_t *)ip; + if (fin->fin_v == 6) { + ip6->ip6_flow = ((ip6_t *)fin->fin_ip)->ip6_flow; + ip6->ip6_plen = htons(iclen - hlen); + ip6->ip6_nxt = IPPROTO_ICMPV6; + ip6->ip6_hlim = 0; + ip6->ip6_src = dst6; + ip6->ip6_dst = fin->fin_src6; + if (xtra > 0) + bcopy((char *)fin->fin_ip + ohlen, + (char *)&icmp->icmp_ip + ohlen, xtra); + icmp->icmp_cksum = in6_cksum(m, IPPROTO_ICMPV6, + sizeof(*ip6), iclen - hlen); + } else +#endif + { + ip2->ip_len = htons(ip2->ip_len); + ip2->ip_off = htons(ip2->ip_off); + ip->ip_p = IPPROTO_ICMP; + ip->ip_src.s_addr = dst4.s_addr; + ip->ip_dst.s_addr = fin->fin_saddr; + + if (xtra > 0) + bcopy((char *)fin->fin_ip + ohlen, + (char *)&icmp->icmp_ip + ohlen, xtra); + icmp->icmp_cksum = ipf_cksum((u_short *)icmp, + sizeof(*icmp) + 8); + ip->ip_len = iclen; + ip->ip_p = IPPROTO_ICMP; + } + err = fr_send_ip(fin, m, &m); + return err; +} + + +#if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) +# if (BSD < 199306) +int iplinit __P((void)); + +int +# else +void iplinit __P((void)); + +void +# endif +iplinit() +{ + if (iplattach() != 0) + printf("IP Filter failed to attach\n"); + ip_init(); +} +#endif /* __FreeBSD_version < 300000 */ + + +int fr_fastroute(m0, mpp, fin, fdp) +mb_t *m0, **mpp; +fr_info_t *fin; +frdest_t *fdp; +{ + register struct ip *ip, *mhip; + register struct mbuf *m = m0; + register struct route *ro; + int len, off, error = 0, hlen, code; + struct ifnet *ifp, *sifp; + struct sockaddr_in *dst; + struct route iproute; + u_short ip_off; + frentry_t *fr; + +#ifdef M_WRITABLE + /* + * HOT FIX/KLUDGE: + * + * If the mbuf we're about to send is not writable (because of + * a cluster reference, for example) we'll need to make a copy + * of it since this routine modifies the contents. + * + * If you have non-crappy network hardware that can transmit data + * from the mbuf, rather than making a copy, this is gonna be a + * problem. + */ + if (M_WRITABLE(m) == 0) { + if ((m0 = m_dup(m, M_DONTWAIT)) != 0) { + FREE_MB_T(m); + m = m0; + *mpp = m; + } else { + error = ENOBUFS; + FREE_MB_T(m); + *mpp = NULL; + fr_frouteok[1]++; + } + } +#endif + +#ifdef USE_INET6 + if (fin->fin_v == 6) { + /* + * currently "to " and "to :ip#" are not supported + * for IPv6 + */ +#if (__FreeBSD_version >= 490000) + return ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); +#else + return ip6_output(m0, NULL, NULL, 0, NULL, NULL); +#endif + } +#endif + + hlen = fin->fin_hlen; + ip = mtod(m0, struct ip *); + + /* + * Route packet. + */ + ro = &iproute; + bzero((caddr_t)ro, sizeof (*ro)); + dst = (struct sockaddr_in *)&ro->ro_dst; + dst->sin_family = AF_INET; + dst->sin_addr = ip->ip_dst; + + fr = fin->fin_fr; + if (fdp != NULL) + ifp = fdp->fd_ifp; + else + ifp = fin->fin_ifp; + + if ((ifp == NULL) && (!fr || !(fr->fr_flags & FR_FASTROUTE))) { + error = -2; + goto bad; + } + + /* + * In case we're here due to "to " being used with "keep state", + * check that we're going in the correct direction. + */ + if ((fr != NULL) && (fin->fin_rev != 0)) { + if ((ifp != NULL) && (fdp == &fr->fr_tif)) + return -1; + } + if (fdp != NULL) { + if (fdp->fd_ip.s_addr != 0) + dst->sin_addr = fdp->fd_ip; + } + + dst->sin_len = sizeof(*dst); + rtalloc(ro); + + if ((ifp == NULL) && (ro->ro_rt != NULL)) + ifp = ro->ro_rt->rt_ifp; + + if ((ro->ro_rt == NULL) || (ifp == NULL)) { + if (in_localaddr(ip->ip_dst)) + error = EHOSTUNREACH; + else + error = ENETUNREACH; + goto bad; + } + if (ro->ro_rt->rt_flags & RTF_GATEWAY) + dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; + if (ro->ro_rt) + ro->ro_rt->rt_use++; + + /* + * For input packets which are being "fastrouted", they won't + * go back through output filtering and miss their chance to get + * NAT'd and counted. + */ + if (fin->fin_out == 0) { + sifp = fin->fin_ifp; + fin->fin_ifp = ifp; + fin->fin_out = 1; + (void) fr_acctpkt(fin, NULL); + fin->fin_fr = NULL; + if (!fr || !(fr->fr_flags & FR_RETMASK)) { + u_32_t pass; + + (void) fr_checkstate(fin, &pass); + } + + switch (fr_checknatout(fin, NULL)) + { + case 0 : + break; + case 1 : + ip->ip_sum = 0; + break; + case -1 : + error = -1; + goto done; + break; + } + + fin->fin_ifp = sifp; + fin->fin_out = 0; + } else + ip->ip_sum = 0; + /* + * If small enough for interface, can just send directly. + */ + if (ip->ip_len <= ifp->if_mtu) { + ip->ip_len = htons(ip->ip_len); + ip->ip_off = htons(ip->ip_off); + + if (!ip->ip_sum) + ip->ip_sum = in_cksum(m, hlen); + error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, + ro->ro_rt); + goto done; + } + /* + * Too large for interface; fragment if possible. + * Must be able to put at least 8 bytes per fragment. + */ + ip_off = ntohs(ip->ip_off); + if (ip_off & IP_DF) { + error = EMSGSIZE; + goto bad; + } + len = (ifp->if_mtu - hlen) &~ 7; + if (len < 8) { + error = EMSGSIZE; + goto bad; + } + + { + int mhlen, firstlen = len; + struct mbuf **mnext = &m->m_act; + + /* + * Loop through length of segment after first fragment, + * make new header and copy data of each part and link onto chain. + */ + m0 = m; + mhlen = sizeof (struct ip); + for (off = hlen + len; off < ip->ip_len; off += len) { +#ifdef MGETHDR + MGETHDR(m, M_DONTWAIT, MT_HEADER); +#else + MGET(m, M_DONTWAIT, MT_HEADER); +#endif + if (m == 0) { + m = m0; + error = ENOBUFS; + goto bad; + } + m->m_data += max_linkhdr; + mhip = mtod(m, struct ip *); + bcopy((char *)ip, (char *)mhip, sizeof(*ip)); + if (hlen > sizeof (struct ip)) { + mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); + IP_HL_A(mhip, mhlen >> 2); + } + m->m_len = mhlen; + mhip->ip_off = ((off - hlen) >> 3) + ip_off; + if (off + len >= ip->ip_len) + len = ip->ip_len - off; + else + mhip->ip_off |= IP_MF; + mhip->ip_len = htons((u_short)(len + mhlen)); + m->m_next = m_copy(m0, off, len); + if (m->m_next == 0) { + error = ENOBUFS; /* ??? */ + goto sendorfree; + } + m->m_pkthdr.len = mhlen + len; + m->m_pkthdr.rcvif = NULL; + mhip->ip_off = htons((u_short)mhip->ip_off); + mhip->ip_sum = 0; + mhip->ip_sum = in_cksum(m, mhlen); + *mnext = m; + mnext = &m->m_act; + } + /* + * Update first fragment by trimming what's been copied out + * and updating header, then send each fragment (in order). + */ + m_adj(m0, hlen + firstlen - ip->ip_len); + ip->ip_len = htons((u_short)(hlen + firstlen)); + ip->ip_off = htons((u_short)IP_MF); + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m0, hlen); +sendorfree: + for (m = m0; m; m = m0) { + m0 = m->m_act; + m->m_act = 0; + if (error == 0) + error = (*ifp->if_output)(ifp, m, + (struct sockaddr *)dst, ro->ro_rt); + else + FREE_MB_T(m); + } + } +done: + if (!error) + fr_frouteok[0]++; + else + fr_frouteok[1]++; + + if (ro->ro_rt) { + RTFREE(ro->ro_rt); + } + *mpp = NULL; + return 0; +bad: + if (error == EMSGSIZE) { + sifp = fin->fin_ifp; + code = fin->fin_icode; + fin->fin_icode = ICMP_UNREACH_NEEDFRAG; + fin->fin_ifp = ifp; + (void) fr_send_icmp_err(ICMP_UNREACH, fin, 1); + fin->fin_ifp = sifp; + fin->fin_icode = code; + } + FREE_MB_T(m); + goto done; +} + + +int fr_verifysrc(fin) +fr_info_t *fin; +{ + struct sockaddr_in *dst; + struct route iproute; + + bzero((char *)&iproute, sizeof(iproute)); + dst = (struct sockaddr_in *)&iproute.ro_dst; + dst->sin_len = sizeof(*dst); + dst->sin_family = AF_INET; + dst->sin_addr = fin->fin_src; + rtalloc(&iproute); + if (iproute.ro_rt == NULL) + return 0; + return (fin->fin_ifp == iproute.ro_rt->rt_ifp); +} + + +/* + * return the first IP Address associated with an interface + */ +int fr_ifpaddr(v, atype, ifptr, inp, inpmask) +int v, atype; +void *ifptr; +struct in_addr *inp, *inpmask; +{ +#ifdef USE_INET6 + struct in6_addr *inp6 = NULL; +#endif + struct sockaddr *sock, *mask; + struct sockaddr_in *sin; + struct ifaddr *ifa; + struct ifnet *ifp; + + if ((ifptr == NULL) || (ifptr == (void *)-1)) + return -1; + + sin = NULL; + ifp = ifptr; + + if (v == 4) + inp->s_addr = 0; +#ifdef USE_INET6 + else if (v == 6) + bzero((char *)inp, sizeof(struct in6_addr)); +#endif +#if (__FreeBSD_version >= 300000) + ifa = TAILQ_FIRST(&ifp->if_addrhead); +#else + ifa = ifp->if_addrlist; +#endif /* __FreeBSD_version >= 300000 */ + + sock = ifa->ifa_addr; + while (sock != NULL && ifa != NULL) { + sin = (struct sockaddr_in *)sock; + if ((v == 4) && (sin->sin_family == AF_INET)) + break; +#ifdef USE_INET6 + if ((v == 6) && (sin->sin_family == AF_INET6)) { + inp6 = &((struct sockaddr_in6 *)sin)->sin6_addr; + if (!IN6_IS_ADDR_LINKLOCAL(inp6) && + !IN6_IS_ADDR_LOOPBACK(inp6)) + break; + } +#endif +#if (__FreeBSD_version >= 300000) + ifa = TAILQ_NEXT(ifa, ifa_link); +#else + ifa = ifa->ifa_next; +#endif /* __FreeBSD_version >= 300000 */ + if (ifa != NULL) + sock = ifa->ifa_addr; + } + + if (ifa == NULL || sin == NULL) + return -1; + + mask = ifa->ifa_netmask; + if (atype == FRI_BROADCAST) + sock = ifa->ifa_broadaddr; + else if (atype == FRI_PEERADDR) + sock = ifa->ifa_dstaddr; + +#ifdef USE_INET6 + if (v == 6) { + return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock, + (struct sockaddr_in6 *)mask, + inp, inpmask); + } +#endif + return fr_ifpfillv4addr(atype, (struct sockaddr_in *)sock, + (struct sockaddr_in *)mask, inp, inpmask); +} + + +u_32_t fr_newisn(fin) +fr_info_t *fin; +{ + u_32_t newiss; +#if (__FreeBSD_version >= 400000) + newiss = arc4random(); +#else + static iss_seq_off = 0; + u_char hash[16]; + MD5_CTX ctx; + + /* + * Compute the base value of the ISS. It is a hash + * of (saddr, sport, daddr, dport, secret). + */ + MD5Init(&ctx); + + MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, + sizeof(fin->fin_fi.fi_src)); + MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, + sizeof(fin->fin_fi.fi_dst)); + MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); + + MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); + + MD5Final(hash, &ctx); + + memcpy(&newiss, hash, sizeof(newiss)); + + /* + * Now increment our "timer", and add it in to + * the computed value. + * + * XXX Use `addin'? + * XXX TCP_ISSINCR too large to use? + */ + iss_seq_off += 0x00010000; + newiss += iss_seq_off; +#endif + return newiss; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: fr_nextipid */ +/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ +/* Parameters: fin(I) - pointer to packet information */ +/* */ +/* Returns the next IPv4 ID to use for this packet. */ +/* ------------------------------------------------------------------------ */ +u_short fr_nextipid(fin) +fr_info_t *fin; +{ +#ifndef RANDOM_IP_ID + static u_short ipid = 0; + u_short id; + + MUTEX_ENTER(&ipf_rw); + id = ipid++; + MUTEX_EXIT(&ipf_rw); +#else + u_short id; + + id = ip_randomid(); +#endif + + return id; +} + + +INLINE void fr_checkv4sum(fin) +fr_info_t *fin; +{ +#ifdef CSUM_DATA_VALID + int manual = 0; + u_short sum; + ip_t *ip; + mb_t *m; + + if ((fin->fin_flx & FI_NOCKSUM) != 0) + return; + + m = fin->fin_m; + if (m == NULL) { + manual = 1; + goto skipauto; + } + ip = fin->fin_ip; + + if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { + if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) + sum = m->m_pkthdr.csum_data; + else + sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, + htonl(m->m_pkthdr.csum_data + + fin->fin_ip->ip_len + fin->fin_p)); + sum ^= 0xffff; + if (sum != 0) + fin->fin_flx |= FI_BAD; + } else + manual = 1; +skipauto: +# ifdef IPFILTER_CKSUM + if (manual != 0) + if (fr_checkl4sum(fin) == -1) + fin->fin_flx |= FI_BAD; +# else + ; +# endif +#else +# ifdef IPFILTER_CKSUM + if (fr_checkl4sum(fin) == -1) + fin->fin_flx |= FI_BAD; +# endif +#endif +} + + +#ifdef USE_INET6 +INLINE void fr_checkv6sum(fin) +fr_info_t *fin; +{ +# ifdef IPFILTER_CKSUM + if (fr_checkl4sum(fin) == -1) + fin->fin_flx |= FI_BAD; +# endif +} +#endif /* USE_INET6 */ + + +size_t mbufchainlen(m0) +struct mbuf *m0; +{ + size_t len; + + if ((m0->m_flags & M_PKTHDR) != 0) { + len = m0->m_pkthdr.len; + } else { + struct mbuf *m; + + for (m = m0, len = 0; m != NULL; m = m->m_next) + len += m->m_len; + } + return len; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: fr_pullup */ +/* Returns: NULL == pullup failed, else pointer to protocol header */ +/* Parameters: m(I) - pointer to buffer where data packet starts */ +/* fin(I) - pointer to packet information */ +/* len(I) - number of bytes to pullup */ +/* */ +/* Attempt to move at least len bytes (from the start of the buffer) into a */ +/* single buffer for ease of access. Operating system native functions are */ +/* used to manage buffers - if necessary. If the entire packet ends up in */ +/* a single buffer, set the FI_COALESCE flag even though fr_coalesce() has */ +/* not been called. Both fin_ip and fin_dp are updated before exiting _IF_ */ +/* and ONLY if the pullup succeeds. */ +/* */ +/* We assume that 'min' is a pointer to a buffer that is part of the chain */ +/* of buffers that starts at *fin->fin_mp. */ +/* ------------------------------------------------------------------------ */ +void *fr_pullup(min, fin, len) +mb_t *min; +fr_info_t *fin; +int len; +{ + int out = fin->fin_out, dpoff, ipoff; + mb_t *m = min; + char *ip; + + if (m == NULL) + return NULL; + + ip = (char *)fin->fin_ip; + if ((fin->fin_flx & FI_COALESCE) != 0) + return ip; + + ipoff = fin->fin_ipoff; + if (fin->fin_dp != NULL) + dpoff = (char *)fin->fin_dp - (char *)ip; + else + dpoff = 0; + + if (M_LEN(m) < len) { +#ifdef MHLEN + /* + * Assume that M_PKTHDR is set and just work with what is left + * rather than check.. + * Should not make any real difference, anyway. + */ + if (len > MHLEN) +#else + if (len > MLEN) +#endif + { +#ifdef HAVE_M_PULLDOWN + if (m_pulldown(m, 0, len, NULL) == NULL) + m = NULL; +#else + FREE_MB_T(*fin->fin_mp); + m = NULL; +#endif + } else + { + m = m_pullup(m, len); + } + *fin->fin_mp = m; + fin->fin_m = m; + if (m == NULL) { + ATOMIC_INCL(frstats[out].fr_pull[1]); + return NULL; + } + ip = MTOD(m, char *) + ipoff; + } + + ATOMIC_INCL(frstats[out].fr_pull[0]); + fin->fin_ip = (ip_t *)ip; + if (fin->fin_dp != NULL) + fin->fin_dp = (char *)fin->fin_ip + dpoff; + + if (len == fin->fin_plen) + fin->fin_flx |= FI_COALESCE; + return ip; +} diff --git a/contrib/ipfilter/ip_htable.c b/contrib/ipfilter/ip_htable.c new file mode 100644 index 000000000000..50aa92627b29 --- /dev/null +++ b/contrib/ipfilter/ip_htable.c @@ -0,0 +1,455 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001, 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#include +#include +#include +#include +#include +#if !defined(_KERNEL) +# include +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#endif +#include +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) +# include +#endif +#if defined(__FreeBSD__) +# include +# include +#endif +#if !defined(__svr4__) && !defined(__SVR4) && !defined(__hpux) && \ + !defined(linux) +# include +#endif +#if defined(_KERNEL) +# include +#else +# include +#endif +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" +/* END OF INCLUDES */ + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ip_htable.c,v 2.34.2.2 2004/10/17 15:49:15 darrenr Exp"; +#endif + +#ifdef IPFILTER_LOOKUP +static iphtent_t *fr_iphmfind __P((iphtable_t *, struct in_addr *)); +static u_long ipht_nomem[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static u_long ipf_nhtables[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static u_long ipf_nhtnodes[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +iphtable_t *ipf_htables[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL }; + + +void fr_htable_unload() +{ + iplookupflush_t fop; + + fop.iplf_unit = IPL_LOGALL; + (void)fr_flushhtable(&fop); +} + + +int fr_gethtablestat(op) +iplookupop_t *op; +{ + iphtstat_t stats; + + if (op->iplo_size != sizeof(stats)) + return EINVAL; + + stats.iphs_tables = ipf_htables[op->iplo_unit]; + stats.iphs_numtables = ipf_nhtables[op->iplo_unit]; + stats.iphs_numnodes = ipf_nhtnodes[op->iplo_unit]; + stats.iphs_nomem = ipht_nomem[op->iplo_unit]; + + return COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + +} + + +/* + * Create a new hash table using the template passed. + */ +int fr_newhtable(op) +iplookupop_t *op; +{ + iphtable_t *iph, *oiph; + char name[FR_GROUPLEN]; + int err, i, unit; + + KMALLOC(iph, iphtable_t *); + if (iph == NULL) + return ENOMEM; + + err = COPYIN(op->iplo_struct, iph, sizeof(*iph)); + if (err != 0) { + KFREE(iph); + return EFAULT; + } + + unit = op->iplo_unit; + if (iph->iph_unit != unit) { + KFREE(iph); + return EINVAL; + } + + if ((op->iplo_arg & IPHASH_ANON) == 0) { + if (fr_findhtable(op->iplo_unit, op->iplo_name) != NULL) { + KFREE(iph); + return EEXIST; + } + } else { + i = IPHASH_ANON; + do { + i++; +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(name, sizeof(name), "%u", i); +#else + (void)sprintf(name, "%u", i); +#endif + for (oiph = ipf_htables[unit]; oiph != NULL; + oiph = oiph->iph_next) + if (strncmp(oiph->iph_name, name, + sizeof(oiph->iph_name)) == 0) + break; + } while (oiph != NULL); + (void)strncpy(iph->iph_name, name, sizeof(iph->iph_name)); + err = COPYOUT(iph, op->iplo_struct, sizeof(*iph)); + if (err != 0) { + KFREE(iph); + return EFAULT; + } + iph->iph_type |= IPHASH_ANON; + } + + KMALLOCS(iph->iph_table, iphtent_t **, + iph->iph_size * sizeof(*iph->iph_table)); + if (iph->iph_table == NULL) { + KFREE(iph); + ipht_nomem[unit]++; + return ENOMEM; + } + + bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); + iph->iph_masks = 0; + + iph->iph_next = ipf_htables[unit]; + iph->iph_pnext = &ipf_htables[unit]; + if (ipf_htables[unit] != NULL) + ipf_htables[unit]->iph_pnext = &iph->iph_next; + ipf_htables[unit] = iph; + + ipf_nhtables[unit]++; + + return 0; +} + + +/* + */ +int fr_removehtable(op) +iplookupop_t *op; +{ + iphtable_t *iph; + + + iph = fr_findhtable(op->iplo_unit, op->iplo_name); + if (iph == NULL) + return ESRCH; + + if (iph->iph_unit != op->iplo_unit) { + return EINVAL; + } + + if (iph->iph_ref != 0) { + return EBUSY; + } + + fr_delhtable(iph); + + return 0; +} + + +void fr_delhtable(iph) +iphtable_t *iph; +{ + iphtent_t *ipe; + int i; + + for (i = 0; i < iph->iph_size; i++) + while ((ipe = iph->iph_table[i]) != NULL) + if (fr_delhtent(iph, ipe) != 0) + return; + + *iph->iph_pnext = iph->iph_next; + if (iph->iph_next != NULL) + iph->iph_next->iph_pnext = iph->iph_pnext; + + ipf_nhtables[iph->iph_unit]--; + + if (iph->iph_ref == 0) { + KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); + KFREE(iph); + } +} + + +void fr_derefhtable(iph) +iphtable_t *iph; +{ + iph->iph_ref--; + if (iph->iph_ref == 0) + fr_delhtable(iph); +} + + +iphtable_t *fr_findhtable(unit, name) +int unit; +char *name; +{ + iphtable_t *iph; + + for (iph = ipf_htables[unit]; iph != NULL; iph = iph->iph_next) + if (strncmp(iph->iph_name, name, sizeof(iph->iph_name)) == 0) + break; + return iph; +} + + +size_t fr_flushhtable(op) +iplookupflush_t *op; +{ + iphtable_t *iph; + size_t freed; + int i; + + freed = 0; + + for (i = 0; i <= IPL_LOGMAX; i++) { + if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) { + while ((iph = ipf_htables[i]) != NULL) { + fr_delhtable(iph); + freed++; + } + } + } + + return freed; +} + + +/* + * Add an entry to a hash table. + */ +int fr_addhtent(iph, ipeo) +iphtable_t *iph; +iphtent_t *ipeo; +{ + iphtent_t *ipe; + u_int hv; + int bits; + + KMALLOC(ipe, iphtent_t *); + if (ipe == NULL) + return -1; + + bcopy((char *)ipeo, (char *)ipe, sizeof(*ipe)); + ipe->ipe_addr.in4_addr &= ipe->ipe_mask.in4_addr; + ipe->ipe_addr.in4_addr = ntohl(ipe->ipe_addr.in4_addr); + bits = count4bits(ipe->ipe_mask.in4_addr); + ipe->ipe_mask.in4_addr = ntohl(ipe->ipe_mask.in4_addr); + + hv = IPE_HASH_FN(ipe->ipe_addr.in4_addr, ipe->ipe_mask.in4_addr, + iph->iph_size); + ipe->ipe_ref = 0; + ipe->ipe_next = iph->iph_table[hv]; + ipe->ipe_pnext = iph->iph_table + hv; + + if (iph->iph_table[hv] != NULL) + iph->iph_table[hv]->ipe_pnext = &ipe->ipe_next; + iph->iph_table[hv] = ipe; + if ((bits >= 0) && (bits != 32)) + iph->iph_masks |= 1 << bits; + + switch (iph->iph_type & ~IPHASH_ANON) + { + case IPHASH_GROUPMAP : + ipe->ipe_ptr = fr_addgroup(ipe->ipe_group, NULL, + iph->iph_flags, IPL_LOGIPF, + fr_active); + break; + + default : + ipe->ipe_ptr = NULL; + ipe->ipe_value = 0; + break; + } + + ipf_nhtnodes[iph->iph_unit]++; + + return 0; +} + + +/* + * Delete an entry from a hash table. + */ +int fr_delhtent(iph, ipe) +iphtable_t *iph; +iphtent_t *ipe; +{ + + if (ipe->ipe_ref != 0) + return EBUSY; + + + *ipe->ipe_pnext = ipe->ipe_next; + if (ipe->ipe_next != NULL) + ipe->ipe_next->ipe_pnext = ipe->ipe_pnext; + + switch (iph->iph_type & ~IPHASH_ANON) + { + case IPHASH_GROUPMAP : + if (ipe->ipe_group != NULL) + fr_delgroup(ipe->ipe_group, IPL_LOGIPF, fr_active); + break; + + default : + ipe->ipe_ptr = NULL; + ipe->ipe_value = 0; + break; + } + + KFREE(ipe); + + ipf_nhtnodes[iph->iph_unit]--; + + return 0; +} + + +void *fr_iphmfindgroup(tptr, aptr) +void *tptr, *aptr; +{ + struct in_addr *addr; + iphtable_t *iph; + iphtent_t *ipe; + void *rval; + + READ_ENTER(&ip_poolrw); + iph = tptr; + addr = aptr; + + ipe = fr_iphmfind(iph, addr); + if (ipe != NULL) + rval = ipe->ipe_ptr; + else + rval = NULL; + RWLOCK_EXIT(&ip_poolrw); + return rval; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: fr_iphmfindip */ +/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ +/* Parameters: tptr(I) - pointer to the pool to search */ +/* version(I) - IP protocol version (4 or 6) */ +/* aptr(I) - pointer to address information */ +/* */ +/* Search the hash table for a given address and return a search result. */ +/* ------------------------------------------------------------------------ */ +int fr_iphmfindip(tptr, version, aptr) +void *tptr, *aptr; +int version; +{ + struct in_addr *addr; + iphtable_t *iph; + iphtent_t *ipe; + int rval; + + if (version != 4) + return -1; + + if (tptr == NULL || aptr == NULL) + return -1; + + iph = tptr; + addr = aptr; + + READ_ENTER(&ip_poolrw); + ipe = fr_iphmfind(iph, addr); + if (ipe != NULL) + rval = 0; + else + rval = 1; + RWLOCK_EXIT(&ip_poolrw); + return rval; +} + + +/* Locks: ip_poolrw */ +static iphtent_t *fr_iphmfind(iph, addr) +iphtable_t *iph; +struct in_addr *addr; +{ + u_32_t hmsk, msk, ips; + iphtent_t *ipe; + u_int hv; + + hmsk = iph->iph_masks; + msk = 0xffffffff; +maskloop: + ips = ntohl(addr->s_addr) & msk; + hv = IPE_HASH_FN(ips, msk, iph->iph_size); + for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_next) { + if (ipe->ipe_mask.in4_addr != msk || + ipe->ipe_addr.in4_addr != ips) { + continue; + } + break; + } + + if ((ipe == NULL) && (hmsk != 0)) { + while (hmsk != 0) { + msk <<= 1; + if (hmsk & 0x80000000) + break; + hmsk <<= 1; + } + if (hmsk != 0) { + hmsk <<= 1; + goto maskloop; + } + } + return ipe; +} + +#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_htable.h b/contrib/ipfilter/ip_htable.h new file mode 100644 index 000000000000..e13845977d09 --- /dev/null +++ b/contrib/ipfilter/ip_htable.h @@ -0,0 +1,71 @@ +/* $NetBSD$ */ + +#ifndef __IP_HTABLE_H__ +#define __IP_HTABLE_H__ + +#include "netinet/ip_lookup.h" + +typedef struct iphtent_s { + struct iphtent_s *ipe_next, **ipe_pnext; + void *ipe_ptr; + i6addr_t ipe_addr; + i6addr_t ipe_mask; + int ipe_ref; + union { + char ipeu_char[16]; + u_long ipeu_long; + u_int ipeu_int; + }ipe_un; +} iphtent_t; + +#define ipe_value ipe_un.ipeu_int +#define ipe_group ipe_un.ipeu_char + +#define IPE_HASH_FN(a, m, s) (((a) * (m)) % (s)) + + +typedef struct iphtable_s { + ipfrwlock_t iph_rwlock; + struct iphtable_s *iph_next, **iph_pnext; + struct iphtent_s **iph_table; + size_t iph_size; /* size of hash table */ + u_long iph_seed; /* hashing seed */ + u_32_t iph_flags; + u_int iph_unit; /* IPL_LOG* */ + u_int iph_ref; + u_int iph_type; /* lookup or group map - IPHASH_* */ + u_int iph_masks; /* IPv4 netmasks in use */ + char iph_name[FR_GROUPLEN]; /* hash table number */ +} iphtable_t; + +/* iph_type */ +#define IPHASH_LOOKUP 0 +#define IPHASH_GROUPMAP 1 +#define IPHASH_ANON 0x80000000 + + +typedef struct iphtstat_s { + iphtable_t *iphs_tables; + u_long iphs_numtables; + u_long iphs_numnodes; + u_long iphs_nomem; + u_long iphs_pad[16]; +} iphtstat_t; + + +extern iphtable_t *ipf_htables[IPL_LOGSIZE]; + +extern void fr_htable_unload __P((void)); +extern int fr_newhtable __P((iplookupop_t *)); +extern iphtable_t *fr_findhtable __P((int, char *)); +extern int fr_removehtable __P((iplookupop_t *)); +extern size_t fr_flushhtable __P((iplookupflush_t *)); +extern int fr_addhtent __P((iphtable_t *, iphtent_t *)); +extern int fr_delhtent __P((iphtable_t *, iphtent_t *)); +extern void fr_derefhtable __P((iphtable_t *)); +extern void fr_delhtable __P((iphtable_t *)); +extern void *fr_iphmfindgroup __P((void *, void *)); +extern int fr_iphmfindip __P((void *, int, void *)); +extern int fr_gethtablestat __P((iplookupop_t *)); + +#endif /* __IP_HTABLE_H__ */ diff --git a/contrib/ipfilter/ip_irc_pxy.c b/contrib/ipfilter/ip_irc_pxy.c new file mode 100644 index 000000000000..45a120f519b6 --- /dev/null +++ b/contrib/ipfilter/ip_irc_pxy.c @@ -0,0 +1,435 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2000-2003 Darren Reed + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp + */ + +#define IPF_IRC_PROXY + +#define IPF_IRCBUFSZ 96 /* This *MUST* be >= 64! */ + + +int ippr_irc_init __P((void)); +void ippr_irc_fini __P((void)); +int ippr_irc_new __P((fr_info_t *, ap_session_t *, nat_t *)); +int ippr_irc_out __P((fr_info_t *, ap_session_t *, nat_t *)); +int ippr_irc_send __P((fr_info_t *, nat_t *)); +int ippr_irc_complete __P((ircinfo_t *, char *, size_t)); +u_short ipf_irc_atoi __P((char **)); + +static frentry_t ircnatfr; + +int irc_proxy_init = 0; + + +/* + * Initialize local structures. + */ +int ippr_irc_init() +{ + bzero((char *)&ircnatfr, sizeof(ircnatfr)); + ircnatfr.fr_ref = 1; + ircnatfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + MUTEX_INIT(&ircnatfr.fr_lock, "IRC proxy rule lock"); + irc_proxy_init = 1; + + return 0; +} + + +void ippr_irc_fini() +{ + if (irc_proxy_init == 1) { + MUTEX_DESTROY(&ircnatfr.fr_lock); + irc_proxy_init = 0; + } +} + + +char *ippr_irc_dcctypes[] = { + "CHAT ", /* CHAT chat ipnumber portnumber */ + "SEND ", /* SEND filename ipnumber portnumber */ + "MOVE ", + "TSEND ", + "SCHAT ", + NULL, +}; + + +/* + * :A PRIVMSG B :^ADCC CHAT chat 0 0^A\r\n + * PRIVMSG B ^ADCC CHAT chat 0 0^A\r\n + */ + + +int ippr_irc_complete(ircp, buf, len) +ircinfo_t *ircp; +char *buf; +size_t len; +{ + register char *s, c; + register size_t i; + u_32_t l; + int j, k; + + ircp->irc_ipnum = 0; + ircp->irc_port = 0; + + if (len < 31) + return 0; + s = buf; + c = *s++; + i = len - 1; + + if ((c != ':') && (c != 'P')) + return 0; + + if (c == ':') { + /* + * Loosely check that the source is a nickname of some sort + */ + s++; + c = *s; + ircp->irc_snick = s; + if (!ISALPHA(c)) + return 0; + i--; + for (c = *s; !ISSPACE(c) && (i > 0); i--) + c = *s++; + if (i < 31) + return 0; + if (c != 'P') + return 0; + } else + ircp->irc_snick = NULL; + + /* + * Check command string + */ + if (strncmp(s, "PRIVMSG ", 8)) + return 0; + i -= 8; + s += 8; + c = *s; + ircp->irc_dnick = s; + + /* + * Loosely check that the destination is a nickname of some sort + */ + if (!ISALPHA(c)) + return 0; + for (; !ISSPACE(c) && (i > 0); i--) + c = *s++; + if (i < 20) + return 0; + s++, + i--; + + /* + * Look for a ^A to start the DCC + */ + c = *s; + if (c == ':') { + s++; + c = *s; + } + + if (strncmp(s, "\001DCC ", 4)) + return 0; + + i -= 4; + s += 4; + + /* + * Check for a recognised DCC command + */ + for (j = 0, k = 0; ippr_irc_dcctypes[j]; j++) { + k = MIN(strlen(ippr_irc_dcctypes[j]), i); + if (!strncmp(ippr_irc_dcctypes[j], s, k)) + break; + } + if (!ippr_irc_dcctypes[j]) + return 0; + + ircp->irc_type = s; + i -= k; + s += k; + + if (i < 11) + return 0; + + /* + * Check for the arg + */ + c = *s; + if (ISSPACE(c)) + return 0; + ircp->irc_arg = s; + for (; (c != ' ') && (c != '\001') && (i > 0); i--) + c = *s++; + + if (c == '\001') /* In reality a ^A can quote another ^A...*/ + return 0; + + if (i < 5) + return 0; + + s++; + i--; + c = *s; + if (!ISDIGIT(c)) + return 0; + ircp->irc_addr = s; + /* + * Get the IP# + */ + for (l = 0; ISDIGIT(c) && (i > 0); i--) { + l *= 10; + l += c - '0'; + c = *s++; + } + + if (i < 4) + return 0; + + if (c != ' ') + return 0; + + ircp->irc_ipnum = l; + s++; + i--; + c = *s; + if (!ISDIGIT(c)) + return 0; + /* + * Get the port# + */ + for (l = 0; ISDIGIT(c) && (i > 0); i--) { + l *= 10; + l += c - '0'; + c = *s++; + } + if (i < 3) + return 0; + if (strncmp(s, "\001\r\n", 3)) + return 0; + s += 3; + ircp->irc_len = s - buf; + ircp->irc_port = l; + return 1; +} + + +int ippr_irc_new(fin, aps, nat) +fr_info_t *fin; +ap_session_t *aps; +nat_t *nat; +{ + ircinfo_t *irc; + + KMALLOC(irc, ircinfo_t *); + if (irc == NULL) + return -1; + + fin = fin; /* LINT */ + nat = nat; /* LINT */ + + aps->aps_data = irc; + aps->aps_psiz = sizeof(ircinfo_t); + + bzero((char *)irc, sizeof(*irc)); + return 0; +} + + +int ippr_irc_send(fin, nat) +fr_info_t *fin; +nat_t *nat; +{ + char ctcpbuf[IPF_IRCBUFSZ], newbuf[IPF_IRCBUFSZ]; + tcphdr_t *tcp, tcph, *tcp2 = &tcph; + int off, inc = 0, i, dlen; + size_t nlen = 0, olen; + struct in_addr swip; + u_short a5, sp; + ircinfo_t *irc; + fr_info_t fi; + nat_t *nat2; + u_int a1; + ip_t *ip; + mb_t *m; +#ifdef MENTAT + mb_t *m1; +#endif + + m = fin->fin_m; + ip = fin->fin_ip; + tcp = (tcphdr_t *)fin->fin_dp; + bzero(ctcpbuf, sizeof(ctcpbuf)); + off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; + +#ifdef __sgi + dlen = fin->fin_plen - off; +#else + dlen = MSGDSIZE(m) - off; +#endif + if (dlen <= 0) + return 0; + COPYDATA(m, off, MIN(sizeof(ctcpbuf), dlen), ctcpbuf); + + if (dlen <= 0) + return 0; + ctcpbuf[sizeof(ctcpbuf) - 1] = '\0'; + *newbuf = '\0'; + + irc = nat->nat_aps->aps_data; + if (ippr_irc_complete(irc, ctcpbuf, dlen) == 0) + return 0; + + /* + * check that IP address in the PORT/PASV reply is the same as the + * sender of the command - prevents using PORT for port scanning. + */ + if (irc->irc_ipnum != ntohl(nat->nat_inip.s_addr)) + return 0; + + a5 = irc->irc_port; + + /* + * Calculate new address parts for the DCC command + */ + a1 = ntohl(ip->ip_src.s_addr); + olen = irc->irc_len; + i = irc->irc_addr - ctcpbuf; + i++; + (void) strncpy(newbuf, ctcpbuf, i); + /* DO NOT change these! */ +#if defined(SNPRINTF) && defined(KERNEL) + SNPRINTF(newbuf, sizeof(newbuf) - i, "%u %u\001\r\n", a1, a5); +#else + (void) sprintf(newbuf, "%u %u\001\r\n", a1, a5); +#endif + + nlen = strlen(newbuf); + inc = nlen - olen; + + if ((inc + ip->ip_len) > 65535) + return 0; + +#ifdef MENTAT + for (m1 = m; m1->b_cont; m1 = m1->b_cont) + ; + if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) { + mblk_t *nm; + + /* alloc enough to keep same trailer space for lower driver */ + nm = allocb(nlen, BPRI_MED); + PANIC((!nm),("ippr_irc_out: allocb failed")); + + nm->b_band = m1->b_band; + nm->b_wptr += nlen; + + m1->b_wptr -= olen; + PANIC((m1->b_wptr < m1->b_rptr), + ("ippr_irc_out: cannot handle fragmented data block")); + + linkb(m1, nm); + } else { +# if SOLARIS && defined(ICK_VALID) + if (m1->b_datap->db_struiolim == m1->b_wptr) + m1->b_datap->db_struiolim += inc; + m1->b_datap->db_struioflag &= ~STRUIO_IP; +# endif + m1->b_wptr += inc; + } +#else + if (inc < 0) + m_adj(m, inc); + /* the mbuf chain will be extended if necessary by m_copyback() */ +#endif + COPYBACK(m, off, nlen, newbuf); + + if (inc != 0) { +#if defined(MENTAT) || defined(__sgi) + register u_32_t sum1, sum2; + + sum1 = ip->ip_len; + sum2 = ip->ip_len + inc; + + /* Because ~1 == -2, We really need ~1 == -1 */ + if (sum1 > sum2) + sum2--; + sum2 -= sum1; + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + + fix_outcksum(fin, &ip->ip_sum, sum2); +#endif + ip->ip_len += inc; + } + + /* + * Add skeleton NAT entry for connection which will come back the + * other way. + */ + sp = htons(a5); + /* + * Don't allow the PORT command to specify a port < 1024 due to + * security crap. + */ + if (ntohs(sp) < 1024) + return 0; + + /* + * The server may not make the connection back from port 20, but + * it is the most likely so use it here to check for a conflicting + * mapping. + */ + bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); + fi.fin_data[0] = sp; + fi.fin_data[1] = fin->fin_data[1]; + nat2 = nat_outlookup(fin, IPN_TCP, nat->nat_p, nat->nat_inip, + ip->ip_dst); + if (nat2 == NULL) { + bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); + bzero((char *)tcp2, sizeof(*tcp2)); + tcp2->th_win = htons(8192); + tcp2->th_sport = sp; + tcp2->th_dport = 0; /* XXX - don't specify remote port */ + fi.fin_state = NULL; + fi.fin_nat = NULL; + fi.fin_data[0] = ntohs(sp); + fi.fin_data[1] = 0; + fi.fin_dp = (char *)tcp2; + fi.fin_fr = &ircnatfr; + fi.fin_dlen = sizeof(*tcp2); + fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); + swip = ip->ip_src; + ip->ip_src = nat->nat_inip; + nat2 = nat_new(&fi, nat->nat_ptr, NULL, + NAT_SLAVE|IPN_TCP|SI_W_DPORT, NAT_OUTBOUND); + if (nat2 != NULL) { + (void) nat_proto(&fi, nat2, 0); + nat_update(&fi, nat2, nat2->nat_ptr); + + (void) fr_addstate(&fi, NULL, SI_W_DPORT); + if (fi.fin_state != NULL) + fr_statederef(&fi, (ipstate_t **)&fi.fin_state); + } + ip->ip_src = swip; + } + return inc; +} + + +int ippr_irc_out(fin, aps, nat) +fr_info_t *fin; +ap_session_t *aps; +nat_t *nat; +{ + aps = aps; /* LINT */ + return ippr_irc_send(fin, nat); +} diff --git a/contrib/ipfilter/ip_lookup.c b/contrib/ipfilter/ip_lookup.c new file mode 100644 index 000000000000..b8323739e6dd --- /dev/null +++ b/contrib/ipfilter/ip_lookup.c @@ -0,0 +1,530 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002-2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#if defined(__osf__) +# define _PROTO_NET_H_ +#endif +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 220000 && defined(_KERNEL) +# include +# include +#else +# include +#endif +#if !defined(_KERNEL) +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#endif +#include +#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) +# ifdef __osf__ +# include +# endif +# include "radix_ipf_local.h" +# define _RADIX_H_ +#endif +#include +#if defined(__FreeBSD__) +# include +# include +#endif +#if defined(_KERNEL) +# include +# if !defined(__SVR4) && !defined(__svr4__) +# include +# endif +#endif +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_pool.h" +#include "netinet/ip_htable.h" +#include "netinet/ip_lookup.h" +/* END OF INCLUDES */ + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.5 2004/07/06 11:16:25 darrenr Exp"; +#endif + +#ifdef IPFILTER_LOOKUP +int ip_lookup_inited = 0; + +static int iplookup_addnode __P((caddr_t)); +static int iplookup_delnode __P((caddr_t data)); +static int iplookup_addtable __P((caddr_t)); +static int iplookup_deltable __P((caddr_t)); +static int iplookup_stats __P((caddr_t)); +static int iplookup_flush __P((caddr_t)); + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_init */ +/* Returns: int - 0 = success, else error */ +/* Parameters: Nil */ +/* */ +/* Initialise all of the subcomponents of the lookup infrstructure. */ +/* ------------------------------------------------------------------------ */ +int ip_lookup_init() +{ + + if (ip_pool_init() == -1) + return -1; + + RWLOCK_INIT(&ip_poolrw, "ip pool rwlock"); + + ip_lookup_inited = 1; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_unload */ +/* Returns: int - 0 = success, else error */ +/* Parameters: Nil */ +/* */ +/* Free up all pool related memory that has been allocated whilst IPFilter */ +/* has been running. Also, do any other deinitialisation required such */ +/* ip_lookup_init() can be called again, safely. */ +/* ------------------------------------------------------------------------ */ +void ip_lookup_unload() +{ + ip_pool_fini(); + fr_htable_unload(); + + if (ip_lookup_inited == 1) { + RW_DESTROY(&ip_poolrw); + ip_lookup_inited = 0; + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_ioctl */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(IO) - pointer to ioctl data to be copied to/from user */ +/* space. */ +/* cmd(I) - ioctl command number */ +/* mode(I) - file mode bits used with open */ +/* */ +/* Handle ioctl commands sent to the ioctl device. For the most part, this */ +/* involves just calling another function to handle the specifics of each */ +/* command. */ +/* ------------------------------------------------------------------------ */ +int ip_lookup_ioctl(data, cmd, mode) +caddr_t data; +ioctlcmd_t cmd; +int mode; +{ + int err; +# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) + int s; +# endif + + mode = mode; /* LINT */ + + SPL_NET(s); + + switch (cmd) + { + case SIOCLOOKUPADDNODE : + case SIOCLOOKUPADDNODEW : + WRITE_ENTER(&ip_poolrw); + err = iplookup_addnode(data); + RWLOCK_EXIT(&ip_poolrw); + break; + + case SIOCLOOKUPDELNODE : + case SIOCLOOKUPDELNODEW : + WRITE_ENTER(&ip_poolrw); + err = iplookup_delnode(data); + RWLOCK_EXIT(&ip_poolrw); + break; + + case SIOCLOOKUPADDTABLE : + WRITE_ENTER(&ip_poolrw); + err = iplookup_addtable(data); + RWLOCK_EXIT(&ip_poolrw); + break; + + case SIOCLOOKUPDELTABLE : + WRITE_ENTER(&ip_poolrw); + err = iplookup_deltable(data); + RWLOCK_EXIT(&ip_poolrw); + break; + + case SIOCLOOKUPSTAT : + case SIOCLOOKUPSTATW : + WRITE_ENTER(&ip_poolrw); + err = iplookup_stats(data); + RWLOCK_EXIT(&ip_poolrw); + break; + + case SIOCLOOKUPFLUSH : + WRITE_ENTER(&ip_poolrw); + err = iplookup_flush(data); + RWLOCK_EXIT(&ip_poolrw); + break; + + default : + err = EINVAL; + break; + } + SPL_X(s); + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_addnode */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Add a new data node to a lookup structure. First, check to see if the */ +/* parent structure refered to by name exists and if it does, then go on to */ +/* add a node to it. */ +/* ------------------------------------------------------------------------ */ +static int iplookup_addnode(data) +caddr_t data; +{ + ip_pool_node_t node, *m; + iplookupop_t op; + iphtable_t *iph; + iphtent_t hte; + ip_pool_t *p; + int err; + + err = 0; + BCOPYIN(data, &op, sizeof(op)); + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; + + switch (op.iplo_type) + { + case IPLT_POOL : + if (op.iplo_size != sizeof(node)) + return EINVAL; + + err = COPYIN(op.iplo_struct, &node, sizeof(node)); + if (err != 0) + return EFAULT; + + p = ip_pool_find(op.iplo_unit, op.iplo_name); + if (p == NULL) + return ESRCH; + + /* + * add an entry to a pool - return an error if it already + * exists remove an entry from a pool - if it exists + * - in both cases, the pool *must* exist! + */ + m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); + if (m) + return EEXIST; + err = ip_pool_insert(p, &node.ipn_addr.adf_addr, + &node.ipn_mask.adf_addr, node.ipn_info); + break; + + case IPLT_HASH : + if (op.iplo_size != sizeof(hte)) + return EINVAL; + + err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); + if (err != 0) + return EFAULT; + + iph = fr_findhtable(op.iplo_unit, op.iplo_name); + if (iph == NULL) + return ESRCH; + err = fr_addhtent(iph, &hte); + break; + + default : + err = EINVAL; + break; + } + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_delnode */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Delete a node from a lookup table by first looking for the table it is */ +/* in and then deleting the entry that gets found. */ +/* ------------------------------------------------------------------------ */ +static int iplookup_delnode(data) +caddr_t data; +{ + ip_pool_node_t node, *m; + iplookupop_t op; + iphtable_t *iph; + iphtent_t hte; + ip_pool_t *p; + int err; + + err = 0; + BCOPYIN(data, &op, sizeof(op)); + + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; + + switch (op.iplo_type) + { + case IPLT_POOL : + if (op.iplo_size != sizeof(node)) + return EINVAL; + + err = COPYIN(op.iplo_struct, &node, sizeof(node)); + if (err != 0) + return EFAULT; + + p = ip_pool_find(op.iplo_unit, op.iplo_name); + if (!p) + return ESRCH; + + m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); + if (m == NULL) + return ENOENT; + err = ip_pool_remove(p, m); + break; + + case IPLT_HASH : + if (op.iplo_size != sizeof(hte)) + return EINVAL; + + err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); + if (err != 0) + return EFAULT; + + iph = fr_findhtable(op.iplo_unit, op.iplo_name); + if (iph == NULL) + return ESRCH; + err = fr_delhtent(iph, &hte); + break; + + default : + err = EINVAL; + break; + } + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_addtable */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Create a new lookup table, if one doesn't already exist using the name */ +/* for this one. */ +/* ------------------------------------------------------------------------ */ +static int iplookup_addtable(data) +caddr_t data; +{ + iplookupop_t op; + int err; + + err = 0; + BCOPYIN(data, &op, sizeof(op)); + + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; + + switch (op.iplo_type) + { + case IPLT_POOL : + if (ip_pool_find(op.iplo_unit, op.iplo_name) != NULL) + err = EEXIST; + else + err = ip_pool_create(&op); + break; + + case IPLT_HASH : + if (fr_findhtable(op.iplo_unit, op.iplo_name) != NULL) + err = EEXIST; + else + err = fr_newhtable(&op); + break; + + default : + err = EINVAL; + break; + } + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_deltable */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Decodes ioctl request to remove a particular hash table or pool and */ +/* calls the relevant function to do the cleanup. */ +/* ------------------------------------------------------------------------ */ +static int iplookup_deltable(data) +caddr_t data; +{ + iplookupop_t op; + int err; + + BCOPYIN(data, &op, sizeof(op)); + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; + + if (op.iplo_arg & IPLT_ANON) + op.iplo_arg &= IPLT_ANON; + + /* + * create a new pool - fail if one already exists with + * the same # + */ + switch (op.iplo_type) + { + case IPLT_POOL : + err = ip_pool_destroy(&op); + break; + + case IPLT_HASH : + err = fr_removehtable(&op); + break; + + default : + err = EINVAL; + break; + } + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_stats */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* Copy statistical information from inside the kernel back to user space. */ +/* ------------------------------------------------------------------------ */ +static int iplookup_stats(data) +caddr_t data; +{ + iplookupop_t op; + int err; + + err = 0; + BCOPYIN(data, &op, sizeof(op)); + + switch (op.iplo_type) + { + case IPLT_POOL : + err = ip_pool_statistics(&op); + break; + + case IPLT_HASH : + err = fr_gethtablestat(&op); + break; + + default : + err = EINVAL; + break; + } + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: iplookup_flush */ +/* Returns: int - 0 = success, else error */ +/* Parameters: data(I) - pointer to data from ioctl call */ +/* */ +/* A flush is called when we want to flush all the nodes from a particular */ +/* entry in the hash table/pool or want to remove all groups from those. */ +/* ------------------------------------------------------------------------ */ +static int iplookup_flush(data) +caddr_t data; +{ + int err, unit, num, type; + iplookupflush_t flush; + + err = 0; + BCOPYIN(data, &flush, sizeof(flush)); + + flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; + + unit = flush.iplf_unit; + if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) + return EINVAL; + + type = flush.iplf_type; + err = EINVAL; + num = 0; + + if (type == IPLT_POOL || type == IPLT_ALL) { + err = 0; + num = ip_pool_flush(&flush); + } + + if (type == IPLT_HASH || type == IPLT_ALL) { + err = 0; + num += fr_flushhtable(&flush); + } + + if (err == 0) { + flush.iplf_count = num; + err = COPYOUT(&flush, data, sizeof(flush)); + } + return err; +} + + +void ip_lookup_deref(type, ptr) +int type; +void *ptr; +{ + if (ptr == NULL) + return; + + WRITE_ENTER(&ip_poolrw); + switch (type) + { + case IPLT_POOL : + ip_pool_deref(ptr); + break; + + case IPLT_HASH : + fr_derefhtable(ptr); + break; + } + RWLOCK_EXIT(&ip_poolrw); +} + + +#else /* IPFILTER_LOOKUP */ + +/*ARGSUSED*/ +int ip_lookup_ioctl(data, cmd, mode) +caddr_t data; +ioctlcmd_t cmd; +int mode; +{ + return EIO; +} +#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_lookup.h b/contrib/ipfilter/ip_lookup.h new file mode 100644 index 000000000000..e9f8cb8afe4d --- /dev/null +++ b/contrib/ipfilter/ip_lookup.h @@ -0,0 +1,65 @@ +/* $NetBSD$ */ + + +#ifndef __IP_LOOKUP_H__ +#define __IP_LOOKUP_H__ + +#if defined(__STDC__) || defined(__GNUC__) +# define SIOCLOOKUPADDTABLE _IOWR('r', 60, struct iplookupop) +# define SIOCLOOKUPDELTABLE _IOWR('r', 61, struct iplookupop) +# define SIOCLOOKUPSTAT _IOWR('r', 64, struct iplookupop) +# define SIOCLOOKUPSTATW _IOW('r', 64, struct iplookupop) +# define SIOCLOOKUPFLUSH _IOWR('r', 65, struct iplookupflush) +# define SIOCLOOKUPADDNODE _IOWR('r', 67, struct iplookupop) +# define SIOCLOOKUPADDNODEW _IOW('r', 67, struct iplookupop) +# define SIOCLOOKUPDELNODE _IOWR('r', 68, struct iplookupop) +# define SIOCLOOKUPDELNODEW _IOW('r', 68, struct iplookupop) +#else +# define SIOCLOOKUPADDTABLE _IOWR(r, 60, struct iplookupop) +# define SIOCLOOKUPDELTABLE _IOWR(r, 61, struct iplookupop) +# define SIOCLOOKUPSTAT _IOWR(r, 64, struct iplookupop) +# define SIOCLOOKUPSTATW _IOW(r, 64, struct iplookupop) +# define SIOCLOOKUPFLUSH _IOWR(r, 65, struct iplookupflush) +# define SIOCLOOKUPADDNODE _IOWR(r, 67, struct iplookupop) +# define SIOCLOOKUPADDNODEW _IOW(r, 67, struct iplookupop) +# define SIOCLOOKUPDELNODE _IOWR(r, 68, struct iplookupop) +# define SIOCLOOKUPDELNODEW _IOW(r, 68, struct iplookupop) +#endif + +typedef struct iplookupop { + int iplo_type; /* IPLT_* */ + int iplo_unit; /* IPL_LOG* */ + u_int iplo_arg; + char iplo_name[FR_GROUPLEN]; + size_t iplo_size; /* sizeof struct at iplo_struct */ + void *iplo_struct; +} iplookupop_t; + +typedef struct iplookupflush { + int iplf_type; /* IPLT_* */ + int iplf_unit; /* IPL_LOG* */ + u_int iplf_arg; + size_t iplf_count; + char iplf_name[FR_GROUPLEN]; +} iplookupflush_t; + +typedef struct iplookuplink { + int ipll_type; /* IPLT_* */ + int ipll_unit; /* IPL_LOG* */ + u_int ipll_num; + char ipll_group[FR_GROUPLEN]; +} iplookuplink_t; + +#define IPLT_ALL -1 +#define IPLT_NONE 0 +#define IPLT_POOL 1 +#define IPLT_HASH 2 + +#define IPLT_ANON 0x80000000 + +extern int ip_lookup_init __P((void)); +extern int ip_lookup_ioctl __P((caddr_t, ioctlcmd_t, int)); +extern void ip_lookup_unload __P((void)); +extern void ip_lookup_deref __P((int, void *)); + +#endif /* __IP_LOOKUP_H__ */ diff --git a/contrib/ipfilter/ip_msnrpc_pxy.c b/contrib/ipfilter/ip_msnrpc_pxy.c new file mode 100644 index 000000000000..187a9645a527 --- /dev/null +++ b/contrib/ipfilter/ip_msnrpc_pxy.c @@ -0,0 +1,328 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2000-2003 by Darren Reed + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Simple DCE transparent proxy for MSN RPC. + * + * ******* NOTE: THIS PROXY DOES NOT DO ADDRESS TRANSLATION ******** + * + * Id: ip_msnrpc_pxy.c,v 2.17.2.1 2005/02/04 10:22:55 darrenr Exp + */ + +#define IPF_MSNRPC_PROXY + +#define IPF_MINMSNRPCLEN 24 +#define IPF_MSNRPCSKIP (2 + 19 + 2 + 2 + 2 + 19 + 2 + 2) + + +typedef struct msnrpchdr { + u_char mrh_major; /* major # == 5 */ + u_char mrh_minor; /* minor # == 0 */ + u_char mrh_type; + u_char mrh_flags; + u_32_t mrh_endian; + u_short mrh_dlen; /* data size */ + u_short mrh_alen; /* authentication length */ + u_32_t mrh_cid; /* call identifier */ + u_32_t mrh_hint; /* allocation hint */ + u_short mrh_ctxt; /* presentation context hint */ + u_char mrh_ccnt; /* cancel count */ + u_char mrh_ans; +} msnrpchdr_t; + +int ippr_msnrpc_init __P((void)); +void ippr_msnrpc_fini __P((void)); +int ippr_msnrpc_new __P((fr_info_t *, ap_session_t *, nat_t *)); +int ippr_msnrpc_out __P((fr_info_t *, ap_session_t *, nat_t *)); +int ippr_msnrpc_in __P((fr_info_t *, ap_session_t *, nat_t *)); +int ippr_msnrpc_check __P((ip_t *, msnrpchdr_t *)); + +static frentry_t msnfr; + +int msn_proxy_init = 0; + +/* + * Initialize local structures. + */ +int ippr_msnrpc_init() +{ + bzero((char *)&msnfr, sizeof(msnfr)); + msnfr.fr_ref = 1; + msnfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + MUTEX_INIT(&msnfr.fr_lock, "MSN RPC proxy rule lock"); + msn_proxy_init = 1; + + return 0; +} + + +void ippr_msnrpc_fini() +{ + if (msn_proxy_init == 1) { + MUTEX_DESTROY(&msnfr.fr_lock); + msn_proxy_init = 0; + } +} + + +int ippr_msnrpc_new(fin, aps, nat) +fr_info_t *fin; +ap_session_t *aps; +nat_t *nat; +{ + msnrpcinfo_t *mri; + + KMALLOC(mri, msnrpcinfo_t *); + if (mri == NULL) + return -1; + aps->aps_data = mri; + aps->aps_psiz = sizeof(msnrpcinfo_t); + + bzero((char *)mri, sizeof(*mri)); + mri->mri_cmd[0] = 0xff; + mri->mri_cmd[1] = 0xff; + return 0; +} + + +int ippr_msnrpc_check(ip, mrh) +ip_t *ip; +msnrpchdr_t *mrh; +{ + if (mrh->mrh_major != 5) + return -1; + if (mrh->mrh_minor != 0) + return -1; + if (mrh->mrh_alen != 0) + return -1; + if (mrh->mrh_endian == 0x10) { + /* Both gateway and packet match endian */ + if (mrh->mrh_dlen > ip->ip_len) + return -1; + if (mrh->mrh_type == 0 || mrh->mrh_type == 2) + if (mrh->mrh_hint > ip->ip_len) + return -1; + } else if (mrh->mrh_endian == 0x10000000) { + /* XXX - Endian mismatch - should be swapping! */ + return -1; + } else { + return -1; + } + return 0; +} + + +int ippr_msnrpc_out(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + msnrpcinfo_t *mri; + msnrpchdr_t *mrh; + tcphdr_t *tcp; + int dlen; + + mri = aps->aps_data; + if (mri == NULL) + return 0; + + tcp = (tcphdr_t *)fin->fin_dp; + dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); + if (dlen < IPF_MINMSNRPCLEN) + return 0; + + mrh = (msnrpchdr_t *)((char *)tcp + (TCP_OFF(tcp) << 2)); + if (ippr_msnrpc_check(ip, mrh)) + return 0; + + mri->mri_valid++; + + switch (mrh->mrh_type) + { + case 0x0b : /* BIND */ + case 0x00 : /* REQUEST */ + break; + case 0x0c : /* BIND ACK */ + case 0x02 : /* RESPONSE */ + default: + return 0; + } + mri->mri_cmd[1] = mrh->mrh_type; + return 0; +} + + +int ippr_msnrpc_in(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + tcphdr_t *tcp, tcph, *tcp2 = &tcph; + int dlen, sz, sz2, i; + msnrpcinfo_t *mri; + msnrpchdr_t *mrh; + fr_info_t fi; + u_short len; + char *s; + + mri = aps->aps_data; + if (mri == NULL) + return 0; + tcp = (tcphdr_t *)fin->fin_dp; + dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); + if (dlen < IPF_MINMSNRPCLEN) + return 0; + + mrh = (msnrpchdr_t *)((char *)tcp + (TCP_OFF(tcp) << 2)); + if (ippr_msnrpc_check(ip, mrh)) + return 0; + + mri->mri_valid++; + + switch (mrh->mrh_type) + { + case 0x0c : /* BIND ACK */ + if (mri->mri_cmd[1] != 0x0b) + return 0; + break; + case 0x02 : /* RESPONSE */ + if (mri->mri_cmd[1] != 0x00) + return 0; + break; + case 0x0b : /* BIND */ + case 0x00 : /* REQUEST */ + default: + return 0; + } + mri->mri_cmd[0] = mrh->mrh_type; + dlen -= sizeof(*mrh); + + /* + * Only processes RESPONSE's + */ + if (mrh->mrh_type != 0x02) + return 0; + + /* + * Skip over some bytes...what are these really ? + */ + if (dlen <= 44) + return 0; + s = (char *)(mrh + 1) + 20; + dlen -= 20; + bcopy(s, (char *)&len, sizeof(len)); + if (len == 1) { + s += 20; + dlen -= 20; + } else if (len == 2) { + s += 24; + dlen -= 24; + } else + return 0; + + if (dlen <= 10) + return 0; + dlen -= 10; + bcopy(s, (char *)&sz, sizeof(sz)); + s += sizeof(sz); + bcopy(s, (char *)&sz2, sizeof(sz2)); + s += sizeof(sz2); + if (sz2 != sz) + return 0; + if (sz > dlen) + return 0; + if (*s++ != 5) + return 0; + if (*s++ != 0) + return 0; + sz -= IPF_MSNRPCSKIP; + s += IPF_MSNRPCSKIP; + dlen -= IPF_MSNRPCSKIP; + + do { + if (sz < 7 || dlen < 7) + break; + bcopy(s, (char *)&len, sizeof(len)); + if (dlen < len) + break; + if (sz < len) + break; + + if (len != 1) + break; + sz -= 3; + i = *(s + 2); + s += 3; + dlen -= 3; + + bcopy(s, (char *)&len, sizeof(len)); + if (dlen < len) + break; + if (sz < len) + break; + s += sizeof(len); + + switch (i) + { + case 7 : + if (len == 2) { + bcopy(s, (char *)&mri->mri_rport, 2); + mri->mri_flags |= 1; + } + break; + case 9 : + if (len == 4) { + bcopy(s, (char *)&mri->mri_raddr, 4); + mri->mri_flags |= 2; + } + break; + default : + break; + } + sz -= len; + s += len; + dlen -= len; + } while (sz > 0); + + if (mri->mri_flags == 3) { + int slen; + + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + bzero((char *)tcp2, sizeof(*tcp2)); + + slen = ip->ip_len; + ip->ip_len = fin->fin_hlen + sizeof(*tcp2); + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + bzero((char *)tcp2, sizeof(*tcp2)); + tcp2->th_win = htons(8192); + TCP_OFF_A(tcp2, 5); + fi.fin_data[0] = htons(mri->mri_rport); + tcp2->th_sport = mri->mri_rport; + fi.fin_data[1] = 0; + tcp2->th_dport = 0; + fi.fin_state = NULL; + fi.fin_nat = NULL; + fi.fin_dlen = sizeof(*tcp2); + fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); + fi.fin_dp = (char *)tcp2; + fi.fin_fi.fi_daddr = ip->ip_dst.s_addr; + fi.fin_fi.fi_saddr = mri->mri_raddr.s_addr; + if (!fi.fin_fr) + fi.fin_fr = &msnfr; + if (fr_stlookup(&fi, NULL, NULL)) { + RWLOCK_EXIT(&ipf_state); + } else { + (void) fr_addstate(&fi, NULL, SI_W_DPORT|SI_CLONE); + if (fi.fin_state != NULL) + fr_statederef(&fi, (ipstate_t **)&fi.fin_state); + } + ip->ip_len = slen; + } + mri->mri_flags = 0; + return 0; +} diff --git a/contrib/ipfilter/ip_pool.c b/contrib/ipfilter/ip_pool.c new file mode 100644 index 000000000000..b6e111bdd946 --- /dev/null +++ b/contrib/ipfilter/ip_pool.c @@ -0,0 +1,786 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001, 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#if defined(__osf__) +# define _PROTO_NET_H_ +#endif +#include +#include +#include +#include +#if !defined(_KERNEL) && !defined(__KERNEL__) +# include +# include +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#else +# include +# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) +# include +# endif +#endif +#include +#if !defined(linux) +# include +#endif +#include +#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) +# include +#endif +#if defined(__SVR4) || defined(__svr4__) +# include +# include +# ifdef _KERNEL +# include +# endif +# include +# include +#endif +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) +# include +#endif + +#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) +# ifdef __osf__ +# include +# endif +# include "radix_ipf_local.h" +# define _RADIX_H_ +#endif +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_pool.h" + +#if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \ + ((BSD >= 198911) && !defined(__osf__) && \ + !defined(__hpux) && !defined(__sgi)) +static int rn_freenode __P((struct radix_node *, void *)); +#endif + +/* END OF INCLUDES */ + +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ip_pool.c,v 2.55.2.12 2005/02/01 04:04:46 darrenr Exp"; +#endif + +#ifdef IPFILTER_LOOKUP + +# ifndef RADIX_NODE_HEAD_LOCK +# define RADIX_NODE_HEAD_LOCK(x) ; +# endif +# ifndef RADIX_NODE_HEAD_UNLOCK +# define RADIX_NODE_HEAD_UNLOCK(x) ; +# endif + +ip_pool_stat_t ipoolstat; +ipfrwlock_t ip_poolrw; + +/* + * Binary tree routines from Sedgewick and enhanced to do ranges of addresses. + * NOTE: Insertion *MUST* be from greatest range to least for it to work! + * These should be replaced, eventually, by something else - most notably a + * interval searching method. The important feature is to be able to find + * the best match. + * + * So why not use a radix tree for this? As the first line implies, it + * has been written to work with a _range_ of addresses. A range is not + * necessarily a match with any given netmask so what we end up dealing + * with is an interval tree. Implementations of these are hard to find + * and the one herein is far from bug free. + * + * Sigh, in the end I became convinced that the bugs the code contained did + * not make it worthwhile not using radix trees. For now the radix tree from + * 4.4 BSD is used, but this is not viewed as a long term solution. + */ +ip_pool_t *ip_pool_list[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL }; + + +#ifdef TEST_POOL +void treeprint __P((ip_pool_t *)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + addrfamily_t a, b; + iplookupop_t op; + ip_pool_t *ipo; + i6addr_t ip; + + RWLOCK_INIT(&ip_poolrw, "poolrw"); + ip_pool_init(); + + bzero((char *)&a, sizeof(a)); + bzero((char *)&b, sizeof(b)); + bzero((char *)&ip, sizeof(ip)); + bzero((char *)&op, sizeof(op)); + strcpy(op.iplo_name, "0"); + + if (ip_pool_create(&op) == 0) + ipo = ip_pool_find(0, "0"); + + a.adf_addr.in4.s_addr = 0x0a010203; + b.adf_addr.in4.s_addr = 0xffffffff; + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + + a.adf_addr.in4.s_addr = 0x0a000000; + b.adf_addr.in4.s_addr = 0xff000000; + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); + + a.adf_addr.in4.s_addr = 0x0a010100; + b.adf_addr.in4.s_addr = 0xffffff00; + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + + a.adf_addr.in4.s_addr = 0x0a010200; + b.adf_addr.in4.s_addr = 0xffffff00; + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); + + a.adf_addr.in4.s_addr = 0x0a010000; + b.adf_addr.in4.s_addr = 0xffff0000; + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + + a.adf_addr.in4.s_addr = 0x0a01020f; + b.adf_addr.in4.s_addr = 0xffffffff; + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); + ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); +#ifdef DEBUG_POOL +treeprint(ipo); +#endif + ip.in4.s_addr = 0x0a00aabb; + printf("search(%#x) = %d (0)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a000001; + printf("search(%#x) = %d (0)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a000101; + printf("search(%#x) = %d (0)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a010001; + printf("search(%#x) = %d (1)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a010101; + printf("search(%#x) = %d (1)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a010201; + printf("search(%#x) = %d (0)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a010203; + printf("search(%#x) = %d (1)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0a01020f; + printf("search(%#x) = %d (1)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + + ip.in4.s_addr = 0x0b00aabb; + printf("search(%#x) = %d (-1)\n", ip.in4.s_addr, + ip_pool_search(ipo, 4, &ip)); + +#ifdef DEBUG_POOL +treeprint(ipo); +#endif + + ip_pool_fini(); + + return 0; +} + + +void +treeprint(ipo) +ip_pool_t *ipo; +{ + ip_pool_node_t *c; + + for (c = ipo->ipo_list; c != NULL; c = c->ipn_next) + printf("Node %p(%s) (%#x/%#x) = %d hits %lu\n", + c, c->ipn_name, c->ipn_addr.adf_addr.in4.s_addr, + c->ipn_mask.adf_addr.in4.s_addr, + c->ipn_info, c->ipn_hits); +} +#endif /* TEST_POOL */ + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_init */ +/* Returns: int - 0 = success, else error */ +/* */ +/* Initialise the routing table data structures where required. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_init() +{ + + bzero((char *)&ipoolstat, sizeof(ipoolstat)); + +#if (!defined(_KERNEL) || (BSD < 199306)) + rn_init(); +#endif + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_fini */ +/* Returns: int - 0 = success, else error */ +/* Locks: WRITE(ipf_global) */ +/* */ +/* Clean up all the pool data structures allocated and call the cleanup */ +/* function for the radix tree that supports the pools. ip_pool_destroy() is*/ +/* used to delete the pools one by one to ensure they're properly freed up. */ +/* ------------------------------------------------------------------------ */ +void ip_pool_fini() +{ + ip_pool_t *p, *q; + iplookupop_t op; + int i; + + ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0); + + for (i = 0; i <= IPL_LOGMAX; i++) { + for (q = ip_pool_list[i]; (p = q) != NULL; ) { + op.iplo_unit = i; + (void)strncpy(op.iplo_name, p->ipo_name, + sizeof(op.iplo_name)); + q = p->ipo_next; + (void) ip_pool_destroy(&op); + } + } + +#if (!defined(_KERNEL) || (BSD < 199306)) + rn_fini(); +#endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_statistics */ +/* Returns: int - 0 = success, else error */ +/* Parameters: op(I) - pointer to lookup operation arguments */ +/* */ +/* Copy the current statistics out into user space, collecting pool list */ +/* pointers as appropriate for later use. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_statistics(op) +iplookupop_t *op; +{ + ip_pool_stat_t stats; + int unit, i, err = 0; + + if (op->iplo_size != sizeof(ipoolstat)) + return EINVAL; + + bcopy((char *)&ipoolstat, (char *)&stats, sizeof(stats)); + unit = op->iplo_unit; + if (unit == IPL_LOGALL) { + for (i = 0; i < IPL_LOGSIZE; i++) + stats.ipls_list[i] = ip_pool_list[i]; + } else if (unit >= 0 && unit < IPL_LOGSIZE) { + if (op->iplo_name[0] != '\0') + stats.ipls_list[unit] = ip_pool_find(unit, + op->iplo_name); + else + stats.ipls_list[unit] = ip_pool_list[unit]; + } else + err = EINVAL; + if (err == 0) + err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); + return err; +} + + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_find */ +/* Returns: int - 0 = success, else error */ +/* Parameters: ipo(I) - pointer to the pool getting the new node. */ +/* */ +/* Find a matching pool inside the collection of pools for a particular */ +/* device, indicated by the unit number. */ +/* ------------------------------------------------------------------------ */ +void *ip_pool_find(unit, name) +int unit; +char *name; +{ + ip_pool_t *p; + + for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next) + if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0) + break; + return p; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_findeq */ +/* Returns: int - 0 = success, else error */ +/* Parameters: ipo(I) - pointer to the pool getting the new node. */ +/* addr(I) - pointer to address information to delete */ +/* mask(I) - */ +/* */ +/* Searches for an exact match of an entry in the pool. */ +/* ------------------------------------------------------------------------ */ +ip_pool_node_t *ip_pool_findeq(ipo, addr, mask) +ip_pool_t *ipo; +addrfamily_t *addr, *mask; +{ + struct radix_node *n; +#ifdef USE_SPL + int s; + + SPL_NET(s); +#endif + RADIX_NODE_HEAD_LOCK(ipo->ipo_head); + n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head); + RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + SPL_X(s); + return (ip_pool_node_t *)n; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_search */ +/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ +/* Parameters: tptr(I) - pointer to the pool to search */ +/* version(I) - IP protocol version (4 or 6) */ +/* dptr(I) - pointer to address information */ +/* */ +/* Search the pool for a given address and return a search result. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_search(tptr, version, dptr) +void *tptr; +int version; +void *dptr; +{ + struct radix_node *rn; + ip_pool_node_t *m; + i6addr_t *addr; + addrfamily_t v; + ip_pool_t *ipo; + int rv; + + ipo = tptr; + if (ipo == NULL) + return -1; + + rv = 1; + m = NULL; + addr = (i6addr_t *)dptr; + bzero(&v, sizeof(v)); + v.adf_len = offsetof(addrfamily_t, adf_addr); + + if (version == 4) { + v.adf_len += sizeof(addr->in4); + v.adf_addr.in4 = addr->in4; +#ifdef USE_INET6 + } else if (version == 6) { + v.adf_len += sizeof(addr->in6); + v.adf_addr.in6 = addr->in6; +#endif + } else + return -1; + + READ_ENTER(&ip_poolrw); + + RADIX_NODE_HEAD_LOCK(ipo->ipo_head); + rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head); + RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + + if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) { + m = (ip_pool_node_t *)rn; + ipo->ipo_hits++; + m->ipn_hits++; + rv = m->ipn_info; + } + RWLOCK_EXIT(&ip_poolrw); + return rv; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_insert */ +/* Returns: int - 0 = success, else error */ +/* Parameters: ipo(I) - pointer to the pool getting the new node. */ +/* addr(I) - address being added as a node */ +/* mask(I) - netmask to with the node being added */ +/* info(I) - extra information to store in this node. */ +/* Locks: WRITE(ip_poolrw) */ +/* */ +/* Add another node to the pool given by ipo. The three parameters passed */ +/* in (addr, mask, info) shold all be stored in the node. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_insert(ipo, addr, mask, info) +ip_pool_t *ipo; +i6addr_t *addr, *mask; +int info; +{ + struct radix_node *rn; + ip_pool_node_t *x; + + ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); + + KMALLOC(x, ip_pool_node_t *); + if (x == NULL) { + return ENOMEM; + } + + bzero(x, sizeof(*x)); + + x->ipn_info = info; + (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name)); + + bcopy(addr, &x->ipn_addr.adf_addr, sizeof(*addr)); + x->ipn_addr.adf_len = sizeof(x->ipn_addr); + bcopy(mask, &x->ipn_mask.adf_addr, sizeof(*mask)); + x->ipn_mask.adf_len = sizeof(x->ipn_mask); + + RADIX_NODE_HEAD_LOCK(ipo->ipo_head); + rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask, + ipo->ipo_head, x->ipn_nodes); + RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); +#ifdef DEBUG_POOL + printf("Added %p at %p\n", x, rn); +#endif + + if (rn == NULL) { + KFREE(x); + return ENOMEM; + } + + x->ipn_next = ipo->ipo_list; + x->ipn_pnext = &ipo->ipo_list; + if (ipo->ipo_list != NULL) + ipo->ipo_list->ipn_pnext = &x->ipn_next; + ipo->ipo_list = x; + + ipoolstat.ipls_nodes++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_create */ +/* Returns: int - 0 = success, else error */ +/* Parameters: op(I) - pointer to iplookup struct with call details */ +/* Locks: WRITE(ip_poolrw) */ +/* */ +/* Creates a new group according to the paramters passed in via the */ +/* iplookupop structure. Does not check to see if the group already exists */ +/* when being inserted - assume this has already been done. If the pool is */ +/* marked as being anonymous, give it a new, unique, identifier. Call any */ +/* other functions required to initialise the structure. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_create(op) +iplookupop_t *op; +{ + char name[FR_GROUPLEN]; + int poolnum, unit; + ip_pool_t *h; + + ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); + + KMALLOC(h, ip_pool_t *); + if (h == NULL) + return ENOMEM; + bzero(h, sizeof(*h)); + + if (rn_inithead((void **)&h->ipo_head, + offsetof(addrfamily_t, adf_addr) << 3) == 0) { + KFREE(h); + return ENOMEM; + } + + unit = op->iplo_unit; + + if ((op->iplo_arg & IPOOL_ANON) != 0) { + ip_pool_t *p; + + poolnum = IPOOL_ANON; + +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(name, sizeof(name), "%x", poolnum); +#else + (void)sprintf(name, "%x", poolnum); +#endif + + for (p = ip_pool_list[unit]; p != NULL; ) { + if (strncmp(name, p->ipo_name, + sizeof(p->ipo_name)) == 0) { + poolnum++; +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(name, sizeof(name), "%x", poolnum); +#else + (void)sprintf(name, "%x", poolnum); +#endif + p = ip_pool_list[unit]; + } else + p = p->ipo_next; + } + + (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name)); + } else { + (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); + } + + h->ipo_ref = 1; + h->ipo_list = NULL; + h->ipo_unit = unit; + h->ipo_next = ip_pool_list[unit]; + if (ip_pool_list[unit] != NULL) + ip_pool_list[unit]->ipo_pnext = &h->ipo_next; + h->ipo_pnext = &ip_pool_list[unit]; + ip_pool_list[unit] = h; + + ipoolstat.ipls_pools++; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_remove */ +/* Returns: int - 0 = success, else error */ +/* Parameters: ipo(I) - pointer to the pool to remove the node from. */ +/* ipe(I) - address being deleted as a node */ +/* Locks: WRITE(ip_poolrw) */ +/* */ +/* Add another node to the pool given by ipo. The three parameters passed */ +/* in (addr, mask, info) shold all be stored in the node. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_remove(ipo, ipe) +ip_pool_t *ipo; +ip_pool_node_t *ipe; +{ + ip_pool_node_t **ipp, *n; + + ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); + + for (ipp = &ipo->ipo_list; (n = *ipp) != NULL; ipp = &n->ipn_next) { + if (ipe == n) { + *n->ipn_pnext = n->ipn_next; + if (n->ipn_next) + n->ipn_next->ipn_pnext = n->ipn_pnext; + break; + } + } + + if (n == NULL) + return ENOENT; + + RADIX_NODE_HEAD_LOCK(ipo->ipo_head); + ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, + ipo->ipo_head); + RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + KFREE(n); + + ipoolstat.ipls_nodes--; + + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_destroy */ +/* Returns: int - 0 = success, else error */ +/* Parameters: op(I) - information about the pool to remove */ +/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* */ +/* Search for a pool using paramters passed in and if it's not otherwise */ +/* busy, free it. */ +/* */ +/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ +/* may not be initialised, we can't use an ASSERT to enforce the locking */ +/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_destroy(op) +iplookupop_t *op; +{ + ip_pool_t *ipo; + + ipo = ip_pool_find(op->iplo_unit, op->iplo_name); + if (ipo == NULL) + return ESRCH; + + if (ipo->ipo_ref != 1) + return EBUSY; + + ip_pool_free(ipo); + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_flush */ +/* Returns: int - number of pools deleted */ +/* Parameters: fp(I) - which pool(s) to flush */ +/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* */ +/* Free all pools associated with the device that matches the unit number */ +/* passed in with operation. */ +/* */ +/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ +/* may not be initialised, we can't use an ASSERT to enforce the locking */ +/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ +/* ------------------------------------------------------------------------ */ +int ip_pool_flush(fp) +iplookupflush_t *fp; +{ + int i, num = 0, unit, err; + ip_pool_t *p, *q; + iplookupop_t op; + + unit = fp->iplf_unit; + + for (i = 0; i <= IPL_LOGMAX; i++) { + if (unit != IPLT_ALL && i != unit) + continue; + for (q = ip_pool_list[i]; (p = q) != NULL; ) { + op.iplo_unit = i; + (void)strncpy(op.iplo_name, p->ipo_name, + sizeof(op.iplo_name)); + q = p->ipo_next; + err = ip_pool_destroy(&op); + if (err == 0) + num++; + else + break; + } + } + return num; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_free */ +/* Returns: void */ +/* Parameters: ipo(I) - pointer to pool structure */ +/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ +/* */ +/* Deletes the pool strucutre passed in from the list of pools and deletes */ +/* all of the address information stored in it, including any tree data */ +/* structures also allocated. */ +/* */ +/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ +/* may not be initialised, we can't use an ASSERT to enforce the locking */ +/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ +/* ------------------------------------------------------------------------ */ +void ip_pool_free(ipo) +ip_pool_t *ipo; +{ + ip_pool_node_t *n; + + RADIX_NODE_HEAD_LOCK(ipo->ipo_head); + while ((n = ipo->ipo_list) != NULL) { + ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, + ipo->ipo_head); + + *n->ipn_pnext = n->ipn_next; + if (n->ipn_next) + n->ipn_next->ipn_pnext = n->ipn_pnext; + + KFREE(n); + + ipoolstat.ipls_nodes--; + } + RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); + + ipo->ipo_list = NULL; + if (ipo->ipo_next != NULL) + ipo->ipo_next->ipo_pnext = ipo->ipo_pnext; + *ipo->ipo_pnext = ipo->ipo_next; + rn_freehead(ipo->ipo_head); + KFREE(ipo); + + ipoolstat.ipls_pools--; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ip_pool_deref */ +/* Returns: void */ +/* Parameters: ipo(I) - pointer to pool structure */ +/* Locks: WRITE(ip_poolrw) */ +/* */ +/* Drop the number of known references to this pool structure by one and if */ +/* we arrive at zero known references, free it. */ +/* ------------------------------------------------------------------------ */ +void ip_pool_deref(ipo) +ip_pool_t *ipo; +{ + + ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); + + ipo->ipo_ref--; + if (ipo->ipo_ref == 0) + ip_pool_free(ipo); +} + + +# if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \ + !defined(__hpux) && !defined(__sgi)) +static int +rn_freenode(struct radix_node *n, void *p) +{ + struct radix_node_head *rnh = p; + struct radix_node *d; + + d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); + if (d != NULL) { + FreeS(d, max_keylen + 2 * sizeof (*d)); + } + return 0; +} + + +void +rn_freehead(rnh) + struct radix_node_head *rnh; +{ + + RADIX_NODE_HEAD_LOCK(rnh); + (*rnh->rnh_walktree)(rnh, rn_freenode, rnh); + + rnh->rnh_addaddr = NULL; + rnh->rnh_deladdr = NULL; + rnh->rnh_matchaddr = NULL; + rnh->rnh_lookup = NULL; + rnh->rnh_walktree = NULL; + RADIX_NODE_HEAD_UNLOCK(rnh); + + Free(rnh); +} +# endif + +#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_pool.h b/contrib/ipfilter/ip_pool.h new file mode 100644 index 000000000000..3e3c07355229 --- /dev/null +++ b/contrib/ipfilter/ip_pool.h @@ -0,0 +1,87 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001, 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ip_pool.h,v 2.26.2.2 2004/03/23 12:44:34 darrenr Exp + */ + +#ifndef __IP_POOL_H__ +#define __IP_POOL_H__ + +#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \ + !defined(linux) && !defined(sun) +# include +extern void rn_freehead __P((struct radix_node_head *)); +# define FreeS(p, z) KFREES(p, z) +extern int max_keylen; +#else +# if defined(__osf__) || defined(__hpux) +# include "radix_ipf_local.h" +# define radix_mask ipf_radix_mask +# define radix_node ipf_radix_node +# define radix_node_head ipf_radix_node_head +# else +# include "radix_ipf.h" +# endif +#endif +#include "netinet/ip_lookup.h" + +#define IP_POOL_NOMATCH 0 +#define IP_POOL_POSITIVE 1 + +typedef struct ip_pool_node { + struct radix_node ipn_nodes[2]; + addrfamily_t ipn_addr; + addrfamily_t ipn_mask; + int ipn_info; + char ipn_name[FR_GROUPLEN]; + u_long ipn_hits; + struct ip_pool_node *ipn_next, **ipn_pnext; +} ip_pool_node_t; + + +typedef struct ip_pool_s { + struct ip_pool_s *ipo_next; + struct ip_pool_s **ipo_pnext; + struct radix_node_head *ipo_head; + ip_pool_node_t *ipo_list; + u_long ipo_hits; + int ipo_unit; + int ipo_flags; + int ipo_ref; + char ipo_name[FR_GROUPLEN]; +} ip_pool_t; + +#define IPOOL_ANON 0x80000000 + + +typedef struct ip_pool_stat { + u_long ipls_pools; + u_long ipls_tables; + u_long ipls_nodes; + ip_pool_t *ipls_list[IPL_LOGSIZE]; +} ip_pool_stat_t; + + +extern ip_pool_stat_t ipoolstat; +extern ip_pool_t *ip_pool_list[IPL_LOGSIZE]; + +extern int ip_pool_search __P((void *, int, void *)); +extern int ip_pool_init __P((void)); +extern void ip_pool_fini __P((void)); +extern int ip_pool_create __P((iplookupop_t *)); +extern int ip_pool_insert __P((ip_pool_t *, i6addr_t *, i6addr_t *, int)); +extern int ip_pool_remove __P((ip_pool_t *, ip_pool_node_t *)); +extern int ip_pool_destroy __P((iplookupop_t *)); +extern void ip_pool_free __P((ip_pool_t *)); +extern void ip_pool_deref __P((ip_pool_t *)); +extern void *ip_pool_find __P((int, char *)); +extern ip_pool_node_t *ip_pool_findeq __P((ip_pool_t *, + addrfamily_t *, addrfamily_t *)); +extern int ip_pool_flush __P((iplookupflush_t *)); +extern int ip_pool_statistics __P((iplookupop_t *)); + +#endif /* __IP_POOL_H__ */ diff --git a/contrib/ipfilter/ip_pptp_pxy.c b/contrib/ipfilter/ip_pptp_pxy.c new file mode 100644 index 000000000000..2511a17600d6 --- /dev/null +++ b/contrib/ipfilter/ip_pptp_pxy.c @@ -0,0 +1,527 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002-2003 by Darren Reed + * + * Simple PPTP transparent proxy for in-kernel use. For use with the NAT + * code. + * + * Id: ip_pptp_pxy.c,v 2.10.2.9 2005/03/16 18:17:34 darrenr Exp + * + */ +#define IPF_PPTP_PROXY + +typedef struct pptp_hdr { + u_short pptph_len; + u_short pptph_type; + u_32_t pptph_cookie; +} pptp_hdr_t; + +#define PPTP_MSGTYPE_CTL 1 +#define PPTP_MTCTL_STARTREQ 1 +#define PPTP_MTCTL_STARTREP 2 +#define PPTP_MTCTL_STOPREQ 3 +#define PPTP_MTCTL_STOPREP 4 +#define PPTP_MTCTL_ECHOREQ 5 +#define PPTP_MTCTL_ECHOREP 6 +#define PPTP_MTCTL_OUTREQ 7 +#define PPTP_MTCTL_OUTREP 8 +#define PPTP_MTCTL_INREQ 9 +#define PPTP_MTCTL_INREP 10 +#define PPTP_MTCTL_INCONNECT 11 +#define PPTP_MTCTL_CLEAR 12 +#define PPTP_MTCTL_DISCONNECT 13 +#define PPTP_MTCTL_WANERROR 14 +#define PPTP_MTCTL_LINKINFO 15 + + +int ippr_pptp_init __P((void)); +void ippr_pptp_fini __P((void)); +int ippr_pptp_new __P((fr_info_t *, ap_session_t *, nat_t *)); +void ippr_pptp_del __P((ap_session_t *)); +int ippr_pptp_inout __P((fr_info_t *, ap_session_t *, nat_t *)); +void ippr_pptp_donatstate __P((fr_info_t *, nat_t *, pptp_pxy_t *)); +int ippr_pptp_message __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); +int ippr_pptp_nextmessage __P((fr_info_t *, nat_t *, pptp_pxy_t *, int)); +int ippr_pptp_mctl __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); + +static frentry_t pptpfr; + +int pptp_proxy_init = 0; +int ippr_pptp_debug = 0; +int ippr_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */ + + +/* + * PPTP application proxy initialization. + */ +int ippr_pptp_init() +{ + bzero((char *)&pptpfr, sizeof(pptpfr)); + pptpfr.fr_ref = 1; + pptpfr.fr_age[0] = ippr_pptp_gretimeout; + pptpfr.fr_age[1] = ippr_pptp_gretimeout; + pptpfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + MUTEX_INIT(&pptpfr.fr_lock, "PPTP proxy rule lock"); + pptp_proxy_init = 1; + + return 0; +} + + +void ippr_pptp_fini() +{ + if (pptp_proxy_init == 1) { + MUTEX_DESTROY(&pptpfr.fr_lock); + pptp_proxy_init = 0; + } +} + + +/* + * Setup for a new PPTP proxy. + */ +int ippr_pptp_new(fin, aps, nat) +fr_info_t *fin; +ap_session_t *aps; +nat_t *nat; +{ + pptp_pxy_t *pptp; + ipnat_t *ipn; + ip_t *ip; + int off; + + ip = fin->fin_ip; + off = fin->fin_hlen + sizeof(udphdr_t); + + if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip, + ip->ip_dst) != NULL) { + if (ippr_pptp_debug > 0) + printf("ippr_pptp_new: GRE session already exists\n"); + return -1; + } + + aps->aps_psiz = sizeof(*pptp); + KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp)); + if (aps->aps_data == NULL) { + if (ippr_pptp_debug > 0) + printf("ippr_pptp_new: malloc for aps_data failed\n"); + return -1; + } + + /* + * Create NAT rule against which the tunnel/transport mapping is + * created. This is required because the current NAT rule does not + * describe GRE but TCP instead. + */ + pptp = aps->aps_data; + bzero((char *)pptp, sizeof(*pptp)); + ipn = &pptp->pptp_rule; + ipn->in_ifps[0] = fin->fin_ifp; + ipn->in_apr = NULL; + ipn->in_use = 1; + ipn->in_hits = 1; + ipn->in_ippip = 1; + if (nat->nat_dir == NAT_OUTBOUND) { + ipn->in_nip = ntohl(nat->nat_outip.s_addr); + ipn->in_outip = fin->fin_saddr; + ipn->in_redir = NAT_MAP; + } else if (nat->nat_dir == NAT_INBOUND) { + ipn->in_nip = 0; + ipn->in_outip = nat->nat_outip.s_addr; + ipn->in_redir = NAT_REDIRECT; + } + ipn->in_inip = nat->nat_inip.s_addr; + ipn->in_inmsk = 0xffffffff; + ipn->in_outmsk = 0xffffffff; + ipn->in_srcip = fin->fin_saddr; + ipn->in_srcmsk = 0xffffffff; + bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0], + sizeof(ipn->in_ifnames[0])); + ipn->in_p = IPPROTO_GRE; + + pptp->pptp_side[0].pptps_wptr = pptp->pptp_side[0].pptps_buffer; + pptp->pptp_side[1].pptps_wptr = pptp->pptp_side[1].pptps_buffer; + return 0; +} + + +void ippr_pptp_donatstate(fin, nat, pptp) +fr_info_t *fin; +nat_t *nat; +pptp_pxy_t *pptp; +{ + fr_info_t fi; + grehdr_t gre; + nat_t *nat2; + u_char p; + ip_t *ip; + + ip = fin->fin_ip; + p = ip->ip_p; + + nat2 = pptp->pptp_nat; + if ((nat2 == NULL) || (pptp->pptp_state == NULL)) { + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + bzero((char *)&gre, sizeof(gre)); + fi.fin_state = NULL; + fi.fin_nat = NULL; + fi.fin_fi.fi_p = IPPROTO_GRE; + fi.fin_fr = &pptpfr; + if ((nat->nat_dir == NAT_OUTBOUND && fin->fin_out) || + (nat->nat_dir == NAT_INBOUND && !fin->fin_out)) { + fi.fin_data[0] = pptp->pptp_call[0]; + fi.fin_data[1] = pptp->pptp_call[1]; + } else { + fi.fin_data[0] = pptp->pptp_call[1]; + fi.fin_data[1] = pptp->pptp_call[0]; + } + ip = fin->fin_ip; + ip->ip_p = IPPROTO_GRE; + fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG); + fi.fin_flx |= FI_IGNORE; + fi.fin_dp = &gre; + gre.gr_flags = htons(1 << 13); + if (fin->fin_out && nat->nat_dir == NAT_INBOUND) { + fi.fin_fi.fi_saddr = fin->fin_fi.fi_daddr; + fi.fin_fi.fi_daddr = nat->nat_outip.s_addr; + } else if (!fin->fin_out && nat->nat_dir == NAT_OUTBOUND) { + fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; + fi.fin_fi.fi_daddr = fin->fin_fi.fi_saddr; + } + } + + /* + * Update NAT timeout/create NAT if missing. + */ + if (nat2 != NULL) + fr_queueback(&nat2->nat_tqe); + else { + nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat, + NAT_SLAVE, nat->nat_dir); + pptp->pptp_nat = nat2; + if (nat2 != NULL) { + (void) nat_proto(&fi, nat2, 0); + nat_update(&fi, nat2, nat2->nat_ptr); + } + } + + READ_ENTER(&ipf_state); + if (pptp->pptp_state != NULL) { + fr_queueback(&pptp->pptp_state->is_sti); + RWLOCK_EXIT(&ipf_state); + } else { + RWLOCK_EXIT(&ipf_state); + if (nat->nat_dir == NAT_INBOUND) + fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; + else + fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; + fi.fin_ifp = NULL; + pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, + 0); + if (fi.fin_state != NULL) + fr_statederef(&fi, (ipstate_t **)&fi.fin_state); + } + ip->ip_p = p; + return; +} + + +/* + * Try and build up the next PPTP message in the TCP stream and if we can + * build it up completely (fits in our buffer) then pass it off to the message + * parsing function. + */ +int ippr_pptp_nextmessage(fin, nat, pptp, rev) +fr_info_t *fin; +nat_t *nat; +pptp_pxy_t *pptp; +int rev; +{ + static char *funcname = "ippr_pptp_nextmessage"; + pptp_side_t *pptps; + u_32_t start, end; + pptp_hdr_t *hdr; + tcphdr_t *tcp; + int dlen, off; + u_short len; + char *msg; + + tcp = fin->fin_dp; + dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); + start = ntohl(tcp->th_seq); + pptps = &pptp->pptp_side[rev]; + off = (char *)tcp - (char *)fin->fin_ip + (TCP_OFF(tcp) << 2) + + fin->fin_ipoff; + + if (dlen <= 0) + return 0; + /* + * If the complete data packet is before what we expect to see + * "next", just ignore it as the chances are we've already seen it. + * The next if statement following this one really just causes packets + * ahead of what we've seen to be dropped, implying that something in + * the middle went missing and we want to see that first. + */ + end = start + dlen; + if (pptps->pptps_next > end && pptps->pptps_next > start) + return 0; + + if (pptps->pptps_next != start) { + if (ippr_pptp_debug > 5) + printf("%s: next (%x) != start (%x)\n", funcname, + pptps->pptps_next, start); + return -1; + } + + msg = (char *)fin->fin_dp + (TCP_OFF(tcp) << 2); + + while (dlen > 0) { + off += pptps->pptps_bytes; + if (pptps->pptps_gothdr == 0) { + /* + * PPTP has an 8 byte header that inclues the cookie. + * The start of every message should include one and + * it should match 1a2b3c4d. Byte order is ignored, + * deliberately, when printing out the error. + */ + len = MIN(8 - pptps->pptps_bytes, dlen); + COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr); + pptps->pptps_bytes += len; + pptps->pptps_wptr += len; + hdr = (pptp_hdr_t *)pptps->pptps_buffer; + if (pptps->pptps_bytes == 8) { + pptps->pptps_next += 8; + if (ntohl(hdr->pptph_cookie) != 0x1a2b3c4d) { + if (ippr_pptp_debug > 1) + printf("%s: bad cookie (%x)\n", + funcname, + hdr->pptph_cookie); + return -1; + } + } + dlen -= len; + msg += len; + off += len; + + pptps->pptps_gothdr = 1; + len = ntohs(hdr->pptph_len); + pptps->pptps_len = len; + pptps->pptps_nexthdr += len; + + /* + * If a message is too big for the buffer, just set + * the fields for the next message to come along. + * The messages defined in RFC 2637 will not exceed + * 512 bytes (in total length) so this is likely a + * bad data packet, anyway. + */ + if (len > sizeof(pptps->pptps_buffer)) { + if (ippr_pptp_debug > 3) + printf("%s: message too big (%d)\n", + funcname, len); + pptps->pptps_next = pptps->pptps_nexthdr; + pptps->pptps_wptr = pptps->pptps_buffer; + pptps->pptps_gothdr = 0; + pptps->pptps_bytes = 0; + pptps->pptps_len = 0; + break; + } + } + + len = MIN(pptps->pptps_len - pptps->pptps_bytes, dlen); + COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr); + pptps->pptps_bytes += len; + pptps->pptps_wptr += len; + pptps->pptps_next += len; + + if (pptps->pptps_len > pptps->pptps_bytes) + break; + + ippr_pptp_message(fin, nat, pptp, pptps); + pptps->pptps_wptr = pptps->pptps_buffer; + pptps->pptps_gothdr = 0; + pptps->pptps_bytes = 0; + pptps->pptps_len = 0; + + start += len; + msg += len; + dlen -= len; + } + + return 0; +} + + +/* + * handle a complete PPTP message + */ +int ippr_pptp_message(fin, nat, pptp, pptps) +fr_info_t *fin; +nat_t *nat; +pptp_pxy_t *pptp; +pptp_side_t *pptps; +{ + pptp_hdr_t *hdr = (pptp_hdr_t *)pptps->pptps_buffer; + + switch (ntohs(hdr->pptph_type)) + { + case PPTP_MSGTYPE_CTL : + ippr_pptp_mctl(fin, nat, pptp, pptps); + break; + + default : + break; + } + return 0; +} + + +/* + * handle a complete PPTP control message + */ +int ippr_pptp_mctl(fin, nat, pptp, pptps) +fr_info_t *fin; +nat_t *nat; +pptp_pxy_t *pptp; +pptp_side_t *pptps; +{ + u_short *buffer = (u_short *)(pptps->pptps_buffer); + pptp_side_t *pptpo; + + if (pptps == &pptp->pptp_side[0]) + pptpo = &pptp->pptp_side[1]; + else + pptpo = &pptp->pptp_side[0]; + + /* + * Breakout to handle all the various messages. Most are just state + * transition. + */ + switch (ntohs(buffer[4])) + { + case PPTP_MTCTL_STARTREQ : + pptps->pptps_state = PPTP_MTCTL_STARTREQ; + break; + case PPTP_MTCTL_STARTREP : + if (pptpo->pptps_state == PPTP_MTCTL_STARTREQ) + pptps->pptps_state = PPTP_MTCTL_STARTREP; + break; + case PPTP_MTCTL_STOPREQ : + pptps->pptps_state = PPTP_MTCTL_STOPREQ; + break; + case PPTP_MTCTL_STOPREP : + if (pptpo->pptps_state == PPTP_MTCTL_STOPREQ) + pptps->pptps_state = PPTP_MTCTL_STOPREP; + break; + case PPTP_MTCTL_ECHOREQ : + pptps->pptps_state = PPTP_MTCTL_ECHOREQ; + break; + case PPTP_MTCTL_ECHOREP : + if (pptpo->pptps_state == PPTP_MTCTL_ECHOREQ) + pptps->pptps_state = PPTP_MTCTL_ECHOREP; + break; + case PPTP_MTCTL_OUTREQ : + pptps->pptps_state = PPTP_MTCTL_OUTREQ; + break; + case PPTP_MTCTL_OUTREP : + if (pptpo->pptps_state == PPTP_MTCTL_OUTREQ) { + pptps->pptps_state = PPTP_MTCTL_OUTREP; + pptp->pptp_call[0] = buffer[7]; + pptp->pptp_call[1] = buffer[6]; + ippr_pptp_donatstate(fin, nat, pptp); + } + break; + case PPTP_MTCTL_INREQ : + pptps->pptps_state = PPTP_MTCTL_INREQ; + break; + case PPTP_MTCTL_INREP : + if (pptpo->pptps_state == PPTP_MTCTL_INREQ) { + pptps->pptps_state = PPTP_MTCTL_INREP; + pptp->pptp_call[0] = buffer[7]; + pptp->pptp_call[1] = buffer[6]; + ippr_pptp_donatstate(fin, nat, pptp); + } + break; + case PPTP_MTCTL_INCONNECT : + pptps->pptps_state = PPTP_MTCTL_INCONNECT; + break; + case PPTP_MTCTL_CLEAR : + pptps->pptps_state = PPTP_MTCTL_CLEAR; + break; + case PPTP_MTCTL_DISCONNECT : + pptps->pptps_state = PPTP_MTCTL_DISCONNECT; + break; + case PPTP_MTCTL_WANERROR : + pptps->pptps_state = PPTP_MTCTL_WANERROR; + break; + case PPTP_MTCTL_LINKINFO : + pptps->pptps_state = PPTP_MTCTL_LINKINFO; + break; + } + + return 0; +} + + +/* + * For outgoing PPTP packets. refresh timeouts for NAT & state entries, if + * we can. If they have disappeared, recreate them. + */ +int ippr_pptp_inout(fin, aps, nat) +fr_info_t *fin; +ap_session_t *aps; +nat_t *nat; +{ + pptp_pxy_t *pptp; + tcphdr_t *tcp; + int rev; + + if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND)) + rev = 1; + else if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND)) + rev = 1; + else + rev = 0; + + tcp = (tcphdr_t *)fin->fin_dp; + if ((tcp->th_flags & TH_OPENING) == TH_OPENING) { + pptp = (pptp_pxy_t *)aps->aps_data; + pptp->pptp_side[1 - rev].pptps_next = ntohl(tcp->th_ack); + pptp->pptp_side[1 - rev].pptps_nexthdr = ntohl(tcp->th_ack); + pptp->pptp_side[rev].pptps_next = ntohl(tcp->th_seq) + 1; + pptp->pptp_side[rev].pptps_nexthdr = ntohl(tcp->th_seq) + 1; + } + return ippr_pptp_nextmessage(fin, nat, (pptp_pxy_t *)aps->aps_data, + rev); +} + + +/* + * clean up after ourselves. + */ +void ippr_pptp_del(aps) +ap_session_t *aps; +{ + pptp_pxy_t *pptp; + + pptp = aps->aps_data; + + if (pptp != NULL) { + /* + * Don't bother changing any of the NAT structure details, + * *_del() is on a callback from aps_free(), from nat_delete() + */ + + READ_ENTER(&ipf_state); + if (pptp->pptp_state != NULL) { + pptp->pptp_state->is_die = fr_ticks + 1; + pptp->pptp_state->is_me = NULL; + fr_queuefront(&pptp->pptp_state->is_sti); + } + RWLOCK_EXIT(&ipf_state); + + pptp->pptp_state = NULL; + pptp->pptp_nat = NULL; + } +} diff --git a/contrib/ipfilter/ip_rpcb_pxy.c b/contrib/ipfilter/ip_rpcb_pxy.c new file mode 100644 index 000000000000..5d0a1ee43dac --- /dev/null +++ b/contrib/ipfilter/ip_rpcb_pxy.c @@ -0,0 +1,1460 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002-2003 by Ryan Beasley + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * Overview: + * This is an in-kernel application proxy for Sun's RPCBIND (nee portmap) + * protocol as defined in RFC1833. It is far from complete, mostly + * lacking in less-likely corner cases, but it's definitely functional. + * + * Invocation: + * rdr /32 port -> port udp proxy rpcbu + * + * If the host running IP Filter is the same as the RPC server, it's + * perfectly legal for both the internal and external addresses and ports + * to match. + * + * When triggered by appropriate IP NAT rules, this proxy works by + * examining data contained in received packets. Requests and replies are + * modified, NAT and state table entries created, etc., as necessary. + */ +/* + * TODO / NOTES + * + * o Must implement locking to protect proxy session data. + * o Fragmentation isn't supported. + * o Only supports UDP. + * o Doesn't support multiple RPC records in a single request. + * o Errors should be more fine-grained. (e.g., malloc failure vs. + * illegal RPCB request / reply) + * o Even with the limit on the total amount of recorded transactions, + * should there be a timeout on transaction removal? + * o There is a potential collision between cloning, wildcard NAT and + * state entries. There should be an appr_getport routine for + * to avoid this. + * o The enclosed hack of STREAMS support is pretty sick and most likely + * broken. + * + * Id: ip_rpcb_pxy.c,v 2.25.2.3 2005/02/04 10:22:56 darrenr Exp + */ + +#define IPF_RPCB_PROXY + +/* + * Function prototypes + */ +int ippr_rpcb_init __P((void)); +void ippr_rpcb_fini __P((void)); +int ippr_rpcb_new __P((fr_info_t *, ap_session_t *, nat_t *)); +void ippr_rpcb_del __P((ap_session_t *)); +int ippr_rpcb_in __P((fr_info_t *, ap_session_t *, nat_t *)); +int ippr_rpcb_out __P((fr_info_t *, ap_session_t *, nat_t *)); + +static void ippr_rpcb_flush __P((rpcb_session_t *)); +static int ippr_rpcb_decodereq __P((fr_info_t *, nat_t *, + rpcb_session_t *, rpc_msg_t *)); +static int ippr_rpcb_skipauth __P((rpc_msg_t *, xdr_auth_t *, u_32_t **)); +static int ippr_rpcb_insert __P((rpcb_session_t *, rpcb_xact_t *)); +static int ippr_rpcb_xdrrpcb __P((rpc_msg_t *, u_32_t *, rpcb_args_t *)); +static int ippr_rpcb_getuaddr __P((rpc_msg_t *, xdr_uaddr_t *, + u_32_t **)); +static u_int ippr_rpcb_atoi __P((char *)); +static int ippr_rpcb_modreq __P((fr_info_t *, nat_t *, rpc_msg_t *, + mb_t *, u_int)); +static int ippr_rpcb_decoderep __P((fr_info_t *, nat_t *, + rpcb_session_t *, rpc_msg_t *, rpcb_xact_t **)); +static rpcb_xact_t * ippr_rpcb_lookup __P((rpcb_session_t *, u_32_t)); +static void ippr_rpcb_deref __P((rpcb_session_t *, rpcb_xact_t *)); +static int ippr_rpcb_getproto __P((rpc_msg_t *, xdr_proto_t *, + u_32_t **)); +static int ippr_rpcb_getnat __P((fr_info_t *, nat_t *, u_int, u_int)); +static int ippr_rpcb_modv3 __P((fr_info_t *, nat_t *, rpc_msg_t *, + mb_t *, u_int)); +static int ippr_rpcb_modv4 __P((fr_info_t *, nat_t *, rpc_msg_t *, + mb_t *, u_int)); +static void ippr_rpcb_fixlen __P((fr_info_t *, int)); + +/* + * Global variables + */ +static frentry_t rpcbfr; /* Skeleton rule for reference by entities + this proxy creates. */ +static int rpcbcnt; /* Upper bound of allocated RPCB sessions. */ + /* XXX rpcbcnt still requires locking. */ + +int rpcb_proxy_init = 0; + + +/* + * Since rpc_msg contains only pointers, one should use this macro as a + * handy way to get to the goods. (In case you're wondering about the name, + * this started as BYTEREF -> BREF -> B.) + */ +#define B(r) (u_32_t)ntohl(*(r)) + +/* + * Public subroutines + */ + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_init */ +/* Returns: int - 0 == success */ +/* Parameters: (void) */ +/* */ +/* Initialize the filter rule entry and session limiter. */ +/* -------------------------------------------------------------------- */ +int +ippr_rpcb_init() +{ + rpcbcnt = 0; + + bzero((char *)&rpcbfr, sizeof(rpcbfr)); + rpcbfr.fr_ref = 1; + rpcbfr.fr_flags = FR_PASS|FR_QUICK|FR_KEEPSTATE; + MUTEX_INIT(&rpcbfr.fr_lock, "ipf Sun RPCB proxy rule lock"); + rpcb_proxy_init = 1; + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_fini */ +/* Returns: void */ +/* Parameters: (void) */ +/* */ +/* Destroy rpcbfr's mutex to avoid a lock leak. */ +/* -------------------------------------------------------------------- */ +void +ippr_rpcb_fini() +{ + if (rpcb_proxy_init == 1) { + MUTEX_DESTROY(&rpcbfr.fr_lock); + rpcb_proxy_init = 0; + } +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_new */ +/* Returns: int - -1 == failure, 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* aps(I) - pointer to proxy session structure */ +/* nat(I) - pointer to NAT session structure */ +/* */ +/* Allocate resources for per-session proxy structures. */ +/* -------------------------------------------------------------------- */ +int +ippr_rpcb_new(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + rpcb_session_t *rs; + + fin = fin; /* LINT */ + nat = nat; /* LINT */ + + KMALLOC(rs, rpcb_session_t *); + if (rs == NULL) + return(-1); + + bzero((char *)rs, sizeof(*rs)); + MUTEX_INIT(&rs->rs_rxlock, "ipf Sun RPCB proxy session lock"); + + aps->aps_data = rs; + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_del */ +/* Returns: void */ +/* Parameters: aps(I) - pointer to proxy session structure */ +/* */ +/* Free up a session's list of RPCB requests. */ +/* -------------------------------------------------------------------- */ +void +ippr_rpcb_del(aps) + ap_session_t *aps; +{ + rpcb_session_t *rs; + rs = (rpcb_session_t *)aps->aps_data; + + MUTEX_ENTER(&rs->rs_rxlock); + ippr_rpcb_flush(rs); + MUTEX_EXIT(&rs->rs_rxlock); + MUTEX_DESTROY(&rs->rs_rxlock); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_in */ +/* Returns: int - APR_ERR(1) == drop the packet, */ +/* APR_ERR(2) == kill the proxy session, */ +/* else change in packet length (in bytes) */ +/* Parameters: fin(I) - pointer to packet information */ +/* ip(I) - pointer to packet header */ +/* aps(I) - pointer to proxy session structure */ +/* nat(I) - pointer to NAT session structure */ +/* */ +/* Given a presumed RPCB request, perform some minor tests and pass off */ +/* for decoding. Also pass packet off for a rewrite if necessary. */ +/* -------------------------------------------------------------------- */ +int +ippr_rpcb_in(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + rpc_msg_t rpcmsg, *rm; + rpcb_session_t *rs; + u_int off, dlen; + mb_t *m; + int rv; + + /* Disallow fragmented or illegally short packets. */ + if ((fin->fin_flx & (FI_FRAG|FI_SHORT)) != 0) + return(APR_ERR(1)); + + /* Perform basic variable initialization. */ + rs = (rpcb_session_t *)aps->aps_data; + + m = fin->fin_m; + off = (char *)fin->fin_dp - (char *)fin->fin_ip; + off += sizeof(udphdr_t) + fin->fin_ipoff; + dlen = fin->fin_dlen - sizeof(udphdr_t); + + /* Disallow packets outside legal range for supported requests. */ + if ((dlen < RPCB_REQMIN) || (dlen > RPCB_REQMAX)) + return(APR_ERR(1)); + + /* Copy packet over to convenience buffer. */ + rm = &rpcmsg; + bzero((char *)rm, sizeof(*rm)); + COPYDATA(m, off, dlen, (caddr_t)&rm->rm_msgbuf); + rm->rm_buflen = dlen; + + /* Send off to decode request. */ + rv = ippr_rpcb_decodereq(fin, nat, rs, rm); + + switch(rv) + { + case -1: + return(APR_ERR(1)); + /*NOTREACHED*/ + break; + case 0: + break; + case 1: + rv = ippr_rpcb_modreq(fin, nat, rm, m, off); + break; + default: + /*CONSTANTCONDITION*/ + IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_req)", rv)); + } + + return(rv); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_out */ +/* Returns: int - APR_ERR(1) == drop the packet, */ +/* APR_ERR(2) == kill the proxy session, */ +/* else change in packet length (in bytes) */ +/* Parameters: fin(I) - pointer to packet information */ +/* ip(I) - pointer to packet header */ +/* aps(I) - pointer to proxy session structure */ +/* nat(I) - pointer to NAT session structure */ +/* */ +/* Given a presumed RPCB reply, perform some minor tests and pass off */ +/* for decoding. If the message indicates a successful request with */ +/* valid addressing information, create NAT and state structures to */ +/* allow direct communication between RPC client and server. */ +/* -------------------------------------------------------------------- */ +int +ippr_rpcb_out(fin, aps, nat) + fr_info_t *fin; + ap_session_t *aps; + nat_t *nat; +{ + rpc_msg_t rpcmsg, *rm; + rpcb_session_t *rs; + rpcb_xact_t *rx; + u_int off, dlen; + int rv, diff; + mb_t *m; + + /* Disallow fragmented or illegally short packets. */ + if ((fin->fin_flx & (FI_FRAG|FI_SHORT)) != 0) + return(APR_ERR(1)); + + /* Perform basic variable initialization. */ + rs = (rpcb_session_t *)aps->aps_data; + + m = fin->fin_m; + off = (char *)fin->fin_dp - (char *)fin->fin_ip; + off += sizeof(udphdr_t) + fin->fin_ipoff; + dlen = fin->fin_dlen - sizeof(udphdr_t); + diff = 0; + + /* Disallow packets outside legal range for supported requests. */ + if ((dlen < RPCB_REPMIN) || (dlen > RPCB_REPMAX)) + return(APR_ERR(1)); + + /* Copy packet over to convenience buffer. */ + rm = &rpcmsg; + bzero((char *)rm, sizeof(*rm)); + COPYDATA(m, off, dlen, (caddr_t)&rm->rm_msgbuf); + rm->rm_buflen = dlen; + + /* Send off to decode reply. */ + rv = ippr_rpcb_decoderep(fin, nat, rs, rm, &rx); + + switch(rv) + { + case -1: /* Bad packet */ + if (rx != NULL) { + MUTEX_ENTER(&rs->rs_rxlock); + ippr_rpcb_deref(rs, rx); + MUTEX_EXIT(&rs->rs_rxlock); + } + return(APR_ERR(1)); + /*NOTREACHED*/ + break; + case 0: /* Negative reply / request rejected */ + break; + case 1: /* Positive reply */ + /* + * With the IP address embedded in a GETADDR(LIST) reply, + * we'll need to rewrite the packet in the very possible + * event that the internal & external addresses aren't the + * same. (i.e., this box is either a router or rpcbind + * only listens on loopback.) + */ + if (nat->nat_inip.s_addr != nat->nat_outip.s_addr) { + if (rx->rx_type == RPCB_RES_STRING) + diff = ippr_rpcb_modv3(fin, nat, rm, m, off); + else if (rx->rx_type == RPCB_RES_LIST) + diff = ippr_rpcb_modv4(fin, nat, rm, m, off); + } + break; + default: + /*CONSTANTCONDITION*/ + IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_decoderep)", rv)); + } + + if (rx != NULL) { + MUTEX_ENTER(&rs->rs_rxlock); + /* XXX Gross hack - I'm overloading the reference + * counter to deal with both threads and retransmitted + * requests. One deref signals that this thread is + * finished with rx, and the other signals that we've + * processed its reply. + */ + ippr_rpcb_deref(rs, rx); + ippr_rpcb_deref(rs, rx); + MUTEX_EXIT(&rs->rs_rxlock); + } + + return(diff); +} + +/* + * Private support subroutines + */ + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_flush */ +/* Returns: void */ +/* Parameters: rs(I) - pointer to RPCB session structure */ +/* */ +/* Simply flushes the list of outstanding transactions, if any. */ +/* -------------------------------------------------------------------- */ +static void +ippr_rpcb_flush(rs) + rpcb_session_t *rs; +{ + rpcb_xact_t *r1, *r2; + + r1 = rs->rs_rxlist; + if (r1 == NULL) + return; + + while (r1 != NULL) { + r2 = r1; + r1 = r1->rx_next; + KFREE(r2); + } +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_decodereq */ +/* Returns: int - -1 == bad request or critical failure, */ +/* 0 == request successfully decoded, */ +/* 1 == request successfully decoded; requires */ +/* address rewrite/modification */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT session structure */ +/* rs(I) - pointer to RPCB session structure */ +/* rm(I) - pointer to RPC message structure */ +/* */ +/* Take a presumed RPCB request, decode it, and store the results in */ +/* the transaction list. If the internal target address needs to be */ +/* modified, store its location in ptr. */ +/* WARNING: It's the responsibility of the caller to make sure there */ +/* is enough room in rs_buf for the basic RPC message "preamble". */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_decodereq(fin, nat, rs, rm) + fr_info_t *fin; + nat_t *nat; + rpcb_session_t *rs; + rpc_msg_t *rm; +{ + rpcb_args_t *ra; + u_32_t xdr, *p; + rpc_call_t *rc; + rpcb_xact_t rx; + int mod; + + p = (u_32_t *)rm->rm_msgbuf; + mod = 0; + + bzero((char *)&rx, sizeof(rx)); + rc = &rm->rm_call; + + rm->rm_xid = p; + rx.rx_xid = B(p++); /* Record this message's XID. */ + + /* Parse out and test the RPC header. */ + if ((B(p++) != RPCB_CALL) || + (B(p++) != RPCB_MSG_VERSION) || + (B(p++) != RPCB_PROG)) + return(-1); + + /* Record the RPCB version and procedure. */ + rc->rc_vers = p++; + rc->rc_proc = p++; + + /* Bypass RPC authentication stuff. */ + if (ippr_rpcb_skipauth(rm, &rc->rc_authcred, &p) != 0) + return(-1); + if (ippr_rpcb_skipauth(rm, &rc->rc_authverf, &p) != 0) + return(-1); + + /* Compare RPCB version and procedure numbers. */ + switch(B(rc->rc_vers)) + { + case 2: + /* This proxy only supports PMAP_GETPORT. */ + if (B(rc->rc_proc) != RPCB_GETPORT) + return(-1); + + /* Portmap requests contain four 4 byte parameters. */ + if (RPCB_BUF_EQ(rm, p, 16) == 0) + return(-1); + + p += 2; /* Skip requested program and version numbers. */ + + /* Sanity check the requested protocol. */ + xdr = B(p); + if (!(xdr == IPPROTO_UDP || xdr == IPPROTO_TCP)) + return(-1); + + rx.rx_type = RPCB_RES_PMAP; + rx.rx_proto = xdr; + break; + case 3: + case 4: + /* GETADDRLIST is exclusive to v4; GETADDR for v3 & v4 */ + switch(B(rc->rc_proc)) + { + case RPCB_GETADDR: + rx.rx_type = RPCB_RES_STRING; + rx.rx_proto = (u_int)fin->fin_p; + break; + case RPCB_GETADDRLIST: + if (B(rc->rc_vers) != 4) + return(-1); + rx.rx_type = RPCB_RES_LIST; + break; + default: + return(-1); + } + + ra = &rc->rc_rpcbargs; + + /* Decode the 'struct rpcb' request. */ + if (ippr_rpcb_xdrrpcb(rm, p, ra) != 0) + return(-1); + + /* Are the target address & port valid? */ + if ((ra->ra_maddr.xu_ip != nat->nat_outip.s_addr) || + (ra->ra_maddr.xu_port != nat->nat_outport)) + return(-1); + + /* Do we need to rewrite this packet? */ + if ((nat->nat_outip.s_addr != nat->nat_inip.s_addr) || + (nat->nat_outport != nat->nat_inport)) + mod = 1; + break; + default: + return(-1); + } + + MUTEX_ENTER(&rs->rs_rxlock); + if (ippr_rpcb_insert(rs, &rx) != 0) { + MUTEX_EXIT(&rs->rs_rxlock); + return(-1); + } + MUTEX_EXIT(&rs->rs_rxlock); + + return(mod); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_skipauth */ +/* Returns: int -- -1 == illegal auth parameters (lengths) */ +/* 0 == valid parameters, pointer advanced */ +/* Parameters: rm(I) - pointer to RPC message structure */ +/* auth(I) - pointer to RPC auth structure */ +/* buf(IO) - pointer to location within convenience buffer */ +/* */ +/* Record auth data length & location of auth data, then advance past */ +/* it. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_skipauth(rm, auth, buf) + rpc_msg_t *rm; + xdr_auth_t *auth; + u_32_t **buf; +{ + u_32_t *p, xdr; + + p = *buf; + + /* Make sure we have enough space for expected fixed auth parms. */ + if (RPCB_BUF_GEQ(rm, p, 8) == 0) + return(-1); + + p++; /* We don't care about auth_flavor. */ + + auth->xa_string.xs_len = p; + xdr = B(p++); /* Length of auth_data */ + + /* Test for absurdity / illegality of auth_data length. */ + if ((XDRALIGN(xdr) < xdr) || (RPCB_BUF_GEQ(rm, p, XDRALIGN(xdr)) == 0)) + return(-1); + + auth->xa_string.xs_str = (char *)p; + + p += XDRALIGN(xdr); /* Advance our location. */ + + *buf = (u_32_t *)p; + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_insert */ +/* Returns: int -- -1 == list insertion failed, */ +/* 0 == item successfully added */ +/* Parameters: rs(I) - pointer to RPCB session structure */ +/* rx(I) - pointer to RPCB transaction structure */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_insert(rs, rx) + rpcb_session_t *rs; + rpcb_xact_t *rx; +{ + rpcb_xact_t *rxp; + + rxp = ippr_rpcb_lookup(rs, rx->rx_xid); + if (rxp != NULL) { + ++rxp->rx_ref; + return(0); + } + + if (rpcbcnt == RPCB_MAXREQS) + return(-1); + + KMALLOC(rxp, rpcb_xact_t *); + if (rxp == NULL) + return(-1); + + bcopy((char *)rx, (char *)rxp, sizeof(*rx)); + + if (rs->rs_rxlist != NULL) + rs->rs_rxlist->rx_pnext = &rxp->rx_next; + + rxp->rx_pnext = &rs->rs_rxlist; + rxp->rx_next = rs->rs_rxlist; + rs->rs_rxlist = rxp; + + rxp->rx_ref = 1; + + ++rpcbcnt; + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_xdrrpcb */ +/* Returns: int -- -1 == failure to properly decode the request */ +/* 0 == rpcb successfully decoded */ +/* Parameters: rs(I) - pointer to RPCB session structure */ +/* p(I) - pointer to location within session buffer */ +/* rpcb(O) - pointer to rpcb (xdr type) structure */ +/* */ +/* Decode a XDR encoded rpcb structure and record its contents in rpcb */ +/* within only the context of TCP/UDP over IP networks. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_xdrrpcb(rm, p, ra) + rpc_msg_t *rm; + u_32_t *p; + rpcb_args_t *ra; +{ + if (!RPCB_BUF_GEQ(rm, p, 20)) + return(-1); + + /* Bypass target program & version. */ + p += 2; + + /* Decode r_netid. Must be "tcp" or "udp". */ + if (ippr_rpcb_getproto(rm, &ra->ra_netid, &p) != 0) + return(-1); + + /* Decode r_maddr. */ + if (ippr_rpcb_getuaddr(rm, &ra->ra_maddr, &p) != 0) + return(-1); + + /* Advance to r_owner and make sure it's empty. */ + if (!RPCB_BUF_EQ(rm, p, 4) || (B(p) != 0)) + return(-1); + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_getuaddr */ +/* Returns: int -- -1 == illegal string, */ +/* 0 == string parsed; contents recorded */ +/* Parameters: rm(I) - pointer to RPC message structure */ +/* xu(I) - pointer to universal address structure */ +/* p(IO) - pointer to location within message buffer */ +/* */ +/* Decode the IP address / port at p and record them in xu. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_getuaddr(rm, xu, p) + rpc_msg_t *rm; + xdr_uaddr_t *xu; + u_32_t **p; +{ + char *c, *i, *b, *pp; + u_int d, dd, l, t; + char uastr[24]; + + /* Test for string length. */ + if (!RPCB_BUF_GEQ(rm, *p, 4)) + return(-1); + + xu->xu_xslen = (*p)++; + xu->xu_xsstr = (char *)*p; + + /* Length check */ + l = B(xu->xu_xslen); + if (l < 11 || l > 23 || !RPCB_BUF_GEQ(rm, *p, XDRALIGN(l))) + return(-1); + + /* Advance p */ + *(char **)p += XDRALIGN(l); + + /* Copy string to local buffer & terminate C style */ + bcopy(xu->xu_xsstr, uastr, l); + uastr[l] = '\0'; + + i = (char *)&xu->xu_ip; + pp = (char *)&xu->xu_port; + + /* + * Expected format: a.b.c.d.e.f where [a-d] correspond to bytes of + * an IP address and [ef] are the bytes of a L4 port. + */ + if (!(ISDIGIT(uastr[0]) && ISDIGIT(uastr[l-1]))) + return(-1); + b = uastr; + for (c = &uastr[1], d = 0, dd = 0; c < &uastr[l-1]; c++) { + if (ISDIGIT(*c)) { + dd = 0; + continue; + } + if (*c == '.') { + if (dd != 0) + return(-1); + + /* Check for ASCII byte. */ + *c = '\0'; + t = ippr_rpcb_atoi(b); + if (t > 255) + return(-1); + + /* Aim b at beginning of the next byte. */ + b = c + 1; + + /* Switch off IP addr vs port parsing. */ + if (d < 4) + i[d++] = t & 0xff; + else + pp[d++ - 4] = t & 0xff; + + dd = 1; + continue; + } + return(-1); + } + if (d != 5) /* String must contain exactly 5 periods. */ + return(-1); + + /* Handle the last byte (port low byte) */ + t = ippr_rpcb_atoi(b); + if (t > 255) + return(-1); + pp[d - 4] = t & 0xff; + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_atoi (XXX should be generic for all proxies) */ +/* Returns: int -- integer representation of supplied string */ +/* Parameters: ptr(I) - input string */ +/* */ +/* Simple version of atoi(3) ripped from ip_rcmd_pxy.c. */ +/* -------------------------------------------------------------------- */ +static u_int +ippr_rpcb_atoi(ptr) + char *ptr; +{ + register char *s = ptr, c; + register u_int i = 0; + + while (((c = *s++) != '\0') && ISDIGIT(c)) { + i *= 10; + i += c - '0'; + } + return i; +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_modreq */ +/* Returns: int -- change in datagram length */ +/* APR_ERR(2) - critical failure */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT session */ +/* rm(I) - pointer to RPC message structure */ +/* m(I) - pointer to mbuf chain */ +/* off(I) - current offset within mbuf chain */ +/* */ +/* When external and internal addresses differ, we rewrite the former */ +/* with the latter. (This is exclusive to protocol versions 3 & 4). */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_modreq(fin, nat, rm, m, off) + fr_info_t *fin; + nat_t *nat; + rpc_msg_t *rm; + mb_t *m; + u_int off; +{ + u_int len, xlen, pos, bogo; + rpcb_args_t *ra; + char uaddr[24]; + udphdr_t *udp; + char *i, *p; + int diff; + + ra = &rm->rm_call.rc_rpcbargs; + i = (char *)&nat->nat_inip.s_addr; + p = (char *)&nat->nat_inport; + + /* Form new string. */ + bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(uaddr, sizeof(uaddr), +#else + (void) sprintf(uaddr, +#endif + "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff, + i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff); + len = strlen(uaddr); + xlen = XDRALIGN(len); + + /* Determine mbuf offset to start writing to. */ + pos = (char *)ra->ra_maddr.xu_xslen - rm->rm_msgbuf; + off += pos; + + /* Write new string length. */ + bogo = htonl(len); + COPYBACK(m, off, 4, (caddr_t)&bogo); + off += 4; + + /* Write new string. */ + COPYBACK(m, off, xlen, uaddr); + off += xlen; + + /* Write in zero r_owner. */ + bogo = 0; + COPYBACK(m, off, 4, (caddr_t)&bogo); + + /* Determine difference in data lengths. */ + diff = xlen - XDRALIGN(B(ra->ra_maddr.xu_xslen)); + + /* + * If our new string has a different length, make necessary + * adjustments. + */ + if (diff != 0) { + udp = fin->fin_dp; + udp->uh_ulen = htons(ntohs(udp->uh_ulen) + diff); + fin->fin_ip->ip_len += diff; + fin->fin_dlen += diff; + fin->fin_plen += diff; + /* XXX Storage lengths. */ + } + + return(diff); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_decoderep */ +/* Returns: int - -1 == bad request or critical failure, */ +/* 0 == valid, negative reply */ +/* 1 == vaddlid, positive reply; needs no changes */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT session structure */ +/* rs(I) - pointer to RPCB session structure */ +/* rm(I) - pointer to RPC message structure */ +/* rxp(O) - pointer to RPCB transaction structure */ +/* */ +/* Take a presumed RPCB reply, extract the XID, search for the original */ +/* request information, and determine whether the request was accepted */ +/* or rejected. With a valid accepted reply, go ahead and create NAT */ +/* and state entries, and finish up by rewriting the packet as */ +/* required. */ +/* */ +/* WARNING: It's the responsibility of the caller to make sure there */ +/* is enough room in rs_buf for the basic RPC message "preamble". */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) + fr_info_t *fin; + nat_t *nat; + rpcb_session_t *rs; + rpc_msg_t *rm; + rpcb_xact_t **rxp; +{ + rpcb_listp_t *rl; + rpcb_entry_t *re; + rpcb_xact_t *rx; + u_32_t xdr, *p; + rpc_resp_t *rr; + int rv, cnt; + + p = (u_32_t *)rm->rm_msgbuf; + + bzero((char *)&rx, sizeof(rx)); + rr = &rm->rm_resp; + + rm->rm_xid = p; + xdr = B(p++); /* Record this message's XID. */ + + /* Lookup XID */ + MUTEX_ENTER(&rs->rs_rxlock); + if ((rx = ippr_rpcb_lookup(rs, xdr)) == NULL) { + MUTEX_EXIT(&rs->rs_rxlock); + return(-1); + } + ++rx->rx_ref; /* per thread reference */ + MUTEX_EXIT(&rs->rs_rxlock); + + *rxp = rx; + + /* Test call vs reply */ + if (B(p++) != RPCB_REPLY) + return(-1); + + /* Test reply_stat */ + switch(B(p++)) + { + case RPCB_MSG_DENIED: + return(0); + case RPCB_MSG_ACCEPTED: + break; + default: + return(-1); + } + + /* Bypass RPC authentication stuff. */ + if (ippr_rpcb_skipauth(rm, &rr->rr_authverf, &p) != 0) + return(-1); + + /* Test accept status */ + if (!RPCB_BUF_GEQ(rm, p, 4)) + return(-1); + if (B(p++) != 0) + return(0); + + /* Parse out the expected reply */ + switch(rx->rx_type) + { + case RPCB_RES_PMAP: + /* There must be only one 4 byte argument. */ + if (!RPCB_BUF_EQ(rm, p, 4)) + return(-1); + + rr->rr_v2 = p; + xdr = B(rr->rr_v2); + + /* Reply w/ a 0 port indicates service isn't registered */ + if (xdr == 0) + return(0); + + /* Is the value sane? */ + if (xdr > 65535) + return(-1); + + /* Create NAT & state table entries. */ + if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, (u_int)xdr) != 0) + return(-1); + break; + case RPCB_RES_STRING: + /* Expecting a XDR string; need 4 bytes for length */ + if (!RPCB_BUF_GEQ(rm, p, 4)) + return(-1); + + rr->rr_v3.xu_str.xs_len = p++; + rr->rr_v3.xu_str.xs_str = (char *)p; + + xdr = B(rr->rr_v3.xu_xslen); + + /* A null string indicates an unregistered service */ + if ((xdr == 0) && RPCB_BUF_EQ(rm, p, 0)) + return(0); + + /* Decode the target IP address / port. */ + if (ippr_rpcb_getuaddr(rm, &rr->rr_v3, &p) != 0) + return(-1); + + /* Validate the IP address and port contained. */ + if (nat->nat_inip.s_addr != rr->rr_v3.xu_ip) + return(-1); + + /* Create NAT & state table entries. */ + if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, + (u_int)rr->rr_v3.xu_port) != 0) + return(-1); + break; + case RPCB_RES_LIST: + if (!RPCB_BUF_GEQ(rm, p, 4)) + return(-1); + /* rpcb_entry_list_ptr */ + switch(B(p)) + { + case 0: + return(0); + /*NOTREACHED*/ + break; + case 1: + break; + default: + return(-1); + } + rl = &rr->rr_v4; + rl->rl_list = p++; + cnt = 0; + + for(;;) { + re = &rl->rl_entries[rl->rl_cnt]; + if (ippr_rpcb_getuaddr(rm, &re->re_maddr, &p) != 0) + return(-1); + if (ippr_rpcb_getproto(rm, &re->re_netid, &p) != 0) + return(-1); + /* re_semantics & re_pfamily length */ + if (!RPCB_BUF_GEQ(rm, p, 12)) + return(-1); + p++; /* Skipping re_semantics. */ + xdr = B(p++); + if ((xdr != 4) || strncmp((char *)p, "inet", 4)) + return(-1); + p++; + if (ippr_rpcb_getproto(rm, &re->re_proto, &p) != 0) + return(-1); + if (!RPCB_BUF_GEQ(rm, p, 4)) + return(-1); + re->re_more = p; + if (B(re->re_more) > 1) /* 0,1 only legal values */ + return(-1); + ++rl->rl_cnt; + ++cnt; + if (B(re->re_more) == 0) + break; + /* Replies in max out at 2; TCP and/or UDP */ + if (cnt > 2) + return(-1); + p++; + } + + for(rl->rl_cnt = 0; rl->rl_cnt < cnt; rl->rl_cnt++) { + re = &rl->rl_entries[rl->rl_cnt]; + rv = ippr_rpcb_getnat(fin, nat, + re->re_proto.xp_proto, + (u_int)re->re_maddr.xu_port); + if (rv != 0) + return(-1); + } + break; + default: + /*CONSTANTCONDITION*/ + IPF_PANIC(1, ("illegal rx_type %d", rx->rx_type)); + } + + return(1); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_lookup */ +/* Returns: rpcb_xact_t * - NULL == no matching record, */ +/* else pointer to relevant entry */ +/* Parameters: rs(I) - pointer to RPCB session */ +/* xid(I) - XID to look for */ +/* -------------------------------------------------------------------- */ +static rpcb_xact_t * +ippr_rpcb_lookup(rs, xid) + rpcb_session_t *rs; + u_32_t xid; +{ + rpcb_xact_t *rx; + + if (rs->rs_rxlist == NULL) + return(NULL); + + for (rx = rs->rs_rxlist; rx != NULL; rx = rx->rx_next) + if (rx->rx_xid == xid) + break; + + return(rx); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_deref */ +/* Returns: (void) */ +/* Parameters: rs(I) - pointer to RPCB session */ +/* rx(I) - pointer to RPC transaction struct to remove */ +/* force(I) - indicates to delete entry regardless of */ +/* reference count */ +/* Locking: rs->rs_rxlock must be held write only */ +/* */ +/* Free the RPCB transaction record rx from the chain of entries. */ +/* -------------------------------------------------------------------- */ +static void +ippr_rpcb_deref(rs, rx) + rpcb_session_t *rs; + rpcb_xact_t *rx; +{ + rs = rs; /* LINT */ + + if (rx == NULL) + return; + + if (--rx->rx_ref != 0) + return; + + if (rx->rx_next != NULL) + rx->rx_next->rx_pnext = rx->rx_pnext; + + *rx->rx_pnext = rx->rx_next; + + KFREE(rx); + + --rpcbcnt; +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_getproto */ +/* Returns: int - -1 == illegal protocol/netid, */ +/* 0 == legal protocol/netid */ +/* Parameters: rm(I) - pointer to RPC message structure */ +/* xp(I) - pointer to netid structure */ +/* p(IO) - pointer to location within packet buffer */ +/* */ +/* Decode netid/proto stored at p and record its numeric value. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_getproto(rm, xp, p) + rpc_msg_t *rm; + xdr_proto_t *xp; + u_32_t **p; +{ + u_int len; + + /* Must have 4 bytes for length & 4 bytes for "tcp" or "udp". */ + if (!RPCB_BUF_GEQ(rm, p, 8)) + return(-1); + + xp->xp_xslen = (*p)++; + xp->xp_xsstr = (char *)*p; + + /* Test the string length. */ + len = B(xp->xp_xslen); + if (len != 3) + return(-1); + + /* Test the actual string & record the protocol accordingly. */ + if (!strncmp((char *)xp->xp_xsstr, "tcp\0", 4)) + xp->xp_proto = IPPROTO_TCP; + else if (!strncmp((char *)xp->xp_xsstr, "udp\0", 4)) + xp->xp_proto = IPPROTO_UDP; + else { + return(-1); + } + + /* Advance past the string. */ + (*p)++; + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_getnat */ +/* Returns: int -- -1 == failed to create table entries, */ +/* 0 == success */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT table entry */ +/* proto(I) - transport protocol for new entries */ +/* port(I) - new port to use w/ wildcard table entries */ +/* */ +/* Create state and NAT entries to handle an anticipated connection */ +/* attempt between RPC client and server. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_getnat(fin, nat, proto, port) + fr_info_t *fin; + nat_t *nat; + u_int proto; + u_int port; +{ + ipnat_t *ipn, ipnat; + tcphdr_t tcp; + ipstate_t *is; + fr_info_t fi; + nat_t *natl; + int nflags; + + ipn = nat->nat_ptr; + + /* Generate dummy fr_info */ + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + fi.fin_out = 0; + fi.fin_src = fin->fin_dst; + fi.fin_dst = nat->nat_outip; + fi.fin_p = proto; + fi.fin_sport = 0; + fi.fin_dport = port & 0xffff; + fi.fin_flx |= FI_IGNORE; + + bzero((char *)&tcp, sizeof(tcp)); + tcp.th_dport = htons(port); + + if (proto == IPPROTO_TCP) { + tcp.th_win = htons(8192); + TCP_OFF_A(&tcp, sizeof(tcphdr_t) >> 2); + fi.fin_dlen = sizeof(tcphdr_t); + tcp.th_flags = TH_SYN; + nflags = NAT_TCP; + } else { + fi.fin_dlen = sizeof(udphdr_t); + nflags = NAT_UDP; + } + + nflags |= SI_W_SPORT|NAT_SEARCH; + fi.fin_dp = &tcp; + fi.fin_plen = fi.fin_hlen + fi.fin_dlen; + + /* + * Search for existing NAT & state entries. Pay close attention to + * mutexes / locks grabbed from lookup routines, as not doing so could + * lead to bad things. + * + * If successful, fr_stlookup returns with ipf_state locked. We have + * no use for this lock, so simply unlock it if necessary. + */ + is = fr_stlookup(&fi, &tcp, NULL); + if (is != NULL) + RWLOCK_EXIT(&ipf_state); + + RWLOCK_EXIT(&ipf_nat); + + WRITE_ENTER(&ipf_nat); + natl = nat_inlookup(&fi, nflags, proto, fi.fin_src, fi.fin_dst); + + if ((natl != NULL) && (is != NULL)) { + MUTEX_DOWNGRADE(&ipf_nat); + return(0); + } + + /* Slightly modify the following structures for actual use in creating + * NAT and/or state entries. We're primarily concerned with stripping + * flags that may be detrimental to the creation process or simply + * shouldn't be associated with a table entry. + */ + fi.fin_fr = &rpcbfr; + fi.fin_flx &= ~FI_IGNORE; + nflags &= ~NAT_SEARCH; + + if (natl == NULL) { + /* XXX Since we're just copying the original ipn contents + * back, would we be better off just sending a pointer to + * the 'temp' copy off to nat_new instead? + */ + /* Generate template/bogus NAT rule. */ + bcopy((char *)ipn, (char *)&ipnat, sizeof(ipnat)); + ipn->in_flags = nflags & IPN_TCPUDP; + ipn->in_apr = NULL; + ipn->in_p = proto; + ipn->in_pmin = htons(fi.fin_dport); + ipn->in_pmax = htons(fi.fin_dport); + ipn->in_pnext = htons(fi.fin_dport); + ipn->in_space = 1; + ipn->in_ippip = 1; + if (ipn->in_flags & IPN_FILTER) { + ipn->in_scmp = 0; + ipn->in_dcmp = 0; + } + *ipn->in_plabel = '\0'; + + /* Create NAT entry. return NULL if this fails. */ + natl = nat_new(&fi, ipn, NULL, nflags|SI_CLONE|NAT_SLAVE, + NAT_INBOUND); + + bcopy((char *)&ipnat, (char *)ipn, sizeof(ipnat)); + + if (natl == NULL) { + MUTEX_DOWNGRADE(&ipf_nat); + return(-1); + } + + ipn->in_use++; + (void) nat_proto(&fi, natl, nflags); + nat_update(&fi, natl, natl->nat_ptr); + } + MUTEX_DOWNGRADE(&ipf_nat); + + if (is == NULL) { + /* Create state entry. Return NULL if this fails. */ + fi.fin_dst = nat->nat_inip; + fi.fin_nat = (void *)natl; + fi.fin_flx |= FI_NATED; + fi.fin_flx &= ~FI_STATE; + nflags &= NAT_TCPUDP; + nflags |= SI_W_SPORT|SI_CLONE; + + is = fr_addstate(&fi, NULL, nflags); + if (is == NULL) { + /* + * XXX nat_delete is private to ip_nat.c. Should + * check w/ Darren about this one. + * + * nat_delete(natl, NL_EXPIRE); + */ + return(-1); + } + if (fi.fin_state != NULL) + fr_statederef(&fi, (ipstate_t **)&fi.fin_state); + } + + return(0); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_modv3 */ +/* Returns: int -- change in packet length */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT session */ +/* rm(I) - pointer to RPC message structure */ +/* m(I) - pointer to mbuf chain */ +/* off(I) - offset within mbuf chain */ +/* */ +/* Write a new universal address string to this packet, adjusting */ +/* lengths as necessary. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_modv3(fin, nat, rm, m, off) + fr_info_t *fin; + nat_t *nat; + rpc_msg_t *rm; + mb_t *m; + u_int off; +{ + u_int len, xlen, pos, bogo; + rpc_resp_t *rr; + char uaddr[24]; + char *i, *p; + int diff; + + rr = &rm->rm_resp; + i = (char *)&nat->nat_outip.s_addr; + p = (char *)&rr->rr_v3.xu_port; + + /* Form new string. */ + bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(uaddr, sizeof(uaddr), +#else + (void) sprintf(uaddr, +#endif + "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff, + i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff); + len = strlen(uaddr); + xlen = XDRALIGN(len); + + /* Determine mbuf offset to write to. */ + pos = (char *)rr->rr_v3.xu_xslen - rm->rm_msgbuf; + off += pos; + + /* Write new string length. */ + bogo = htonl(len); + COPYBACK(m, off, 4, (caddr_t)&bogo); + off += 4; + + /* Write new string. */ + COPYBACK(m, off, xlen, uaddr); + + /* Determine difference in data lengths. */ + diff = xlen - XDRALIGN(B(rr->rr_v3.xu_xslen)); + + /* + * If our new string has a different length, make necessary + * adjustments. + */ + if (diff != 0) + ippr_rpcb_fixlen(fin, diff); + + return(diff); +} + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_modv4 */ +/* Returns: int -- change in packet length */ +/* Parameters: fin(I) - pointer to packet information */ +/* nat(I) - pointer to NAT session */ +/* rm(I) - pointer to RPC message structure */ +/* m(I) - pointer to mbuf chain */ +/* off(I) - offset within mbuf chain */ +/* */ +/* Write new rpcb_entry list, adjusting lengths as necessary. */ +/* -------------------------------------------------------------------- */ +static int +ippr_rpcb_modv4(fin, nat, rm, m, off) + fr_info_t *fin; + nat_t *nat; + rpc_msg_t *rm; + mb_t *m; + u_int off; +{ + u_int len, xlen, pos, bogo; + rpcb_listp_t *rl; + rpcb_entry_t *re; + rpc_resp_t *rr; + char uaddr[24]; + int diff, cnt; + char *i, *p; + + diff = 0; + rr = &rm->rm_resp; + rl = &rr->rr_v4; + + i = (char *)&nat->nat_outip.s_addr; + + /* Determine mbuf offset to write to. */ + re = &rl->rl_entries[0]; + pos = (char *)re->re_maddr.xu_xslen - rm->rm_msgbuf; + off += pos; + + for (cnt = 0; cnt < rl->rl_cnt; cnt++) { + re = &rl->rl_entries[cnt]; + p = (char *)&re->re_maddr.xu_port; + + /* Form new string. */ + bzero(uaddr, sizeof(uaddr)); /* Just in case we need + padding. */ +#if defined(SNPRINTF) && defined(_KERNEL) + SNPRINTF(uaddr, sizeof(uaddr), +#else + (void) sprintf(uaddr, +#endif + "%u.%u.%u.%u.%u.%u", i[0] & 0xff, + i[1] & 0xff, i[2] & 0xff, i[3] & 0xff, + p[0] & 0xff, p[1] & 0xff); + len = strlen(uaddr); + xlen = XDRALIGN(len); + + /* Write new string length. */ + bogo = htonl(len); + COPYBACK(m, off, 4, (caddr_t)&bogo); + off += 4; + + /* Write new string. */ + COPYBACK(m, off, xlen, uaddr); + off += xlen; + + /* Record any change in length. */ + diff += xlen - XDRALIGN(B(re->re_maddr.xu_xslen)); + + /* If the length changed, copy back the rest of this entry. */ + len = ((char *)re->re_more + 4) - + (char *)re->re_netid.xp_xslen; + if (diff != 0) { + COPYBACK(m, off, len, (caddr_t)re->re_netid.xp_xslen); + } + off += len; + } + + /* + * If our new string has a different length, make necessary + * adjustments. + */ + if (diff != 0) + ippr_rpcb_fixlen(fin, diff); + + return(diff); +} + + +/* -------------------------------------------------------------------- */ +/* Function: ippr_rpcb_fixlen */ +/* Returns: (void) */ +/* Parameters: fin(I) - pointer to packet information */ +/* len(I) - change in packet length */ +/* */ +/* Adjust various packet related lengths held in structure and packet */ +/* header fields. */ +/* -------------------------------------------------------------------- */ +static void +ippr_rpcb_fixlen(fin, len) + fr_info_t *fin; + int len; +{ + udphdr_t *udp; + + udp = fin->fin_dp; + udp->uh_ulen = htons(ntohs(udp->uh_ulen) + len); + fin->fin_ip->ip_len += len; + fin->fin_dlen += len; + fin->fin_plen += len; +} + +#undef B diff --git a/contrib/ipfilter/ip_scan.c b/contrib/ipfilter/ip_scan.c new file mode 100644 index 000000000000..37f6d58ef167 --- /dev/null +++ b/contrib/ipfilter/ip_scan.c @@ -0,0 +1,594 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1995-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#include +#if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) +# include +#endif +#include +#include +#include +#if !defined(_KERNEL) +# include +# include +# define _KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +#else +# include +# if !defined(__svr4__) && !defined(__SVR4) +# include +# endif +#endif +#include +#if !defined(__hpux) && !defined(__osf__) && !defined(linux) +# include +#endif +#ifdef __FreeBSD__ +# include +# include +#else +# include +#endif + +#include +#include +#include +#include + +#include + + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_state.h" +#include "netinet/ip_scan.h" +/* END OF INCLUDES */ + +#if !defined(lint) +static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ip_scan.c,v 2.40.2.2 2005/01/18 10:13:16 darrenr Exp"; +#endif + +#ifdef IPFILTER_SCAN /* endif at bottom of file */ + + +ipscan_t *ipsc_list = NULL, + *ipsc_tail = NULL; +ipscanstat_t ipsc_stat; +# ifdef USE_MUTEXES +ipfrwlock_t ipsc_rwlock; +# endif + +# ifndef isalpha +# define isalpha(x) (((x) >= 'A' && 'Z' >= (x)) || \ + ((x) >= 'a' && 'z' >= (x))) +# endif + + +int ipsc_add __P((caddr_t)); +int ipsc_delete __P((caddr_t)); +struct ipscan *ipsc_lookup __P((char *)); +int ipsc_matchstr __P((sinfo_t *, char *, int)); +int ipsc_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *)); +int ipsc_match __P((ipstate_t *)); + + + +int ipsc_init() +{ + RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock"); + return 0; +} + + +void fr_scanunload() +{ + RW_DESTROY(&ipsc_rwlock); +} + + +int ipsc_add(data) +caddr_t data; +{ + ipscan_t *i, *isc; + int err; + + KMALLOC(isc, ipscan_t *); + if (!isc) + return ENOMEM; + + err = copyinptr(data, isc, sizeof(*isc)); + if (err) + return err; + + WRITE_ENTER(&ipsc_rwlock); + + i = ipsc_lookup(isc->ipsc_tag); + if (i) { + RWLOCK_EXIT(&ipsc_rwlock); + KFREE(isc); + return EEXIST; + } + + if (ipsc_tail) { + ipsc_tail->ipsc_next = isc; + isc->ipsc_pnext = &ipsc_tail->ipsc_next; + ipsc_tail = isc; + } else { + ipsc_list = isc; + ipsc_tail = isc; + isc->ipsc_pnext = &ipsc_list; + } + isc->ipsc_next = NULL; + + isc->ipsc_hits = 0; + isc->ipsc_fref = 0; + isc->ipsc_sref = 0; + isc->ipsc_active = 0; + + ipsc_stat.iscs_entries++; + RWLOCK_EXIT(&ipsc_rwlock); + return 0; +} + + +int ipsc_delete(data) +caddr_t data; +{ + ipscan_t isc, *i; + int err; + + err = copyinptr(data, &isc, sizeof(isc)); + if (err) + return err; + + WRITE_ENTER(&ipsc_rwlock); + + i = ipsc_lookup(isc.ipsc_tag); + if (i == NULL) + err = ENOENT; + else { + if (i->ipsc_fref) { + RWLOCK_EXIT(&ipsc_rwlock); + return EBUSY; + } + + *i->ipsc_pnext = i->ipsc_next; + if (i->ipsc_next) + i->ipsc_next->ipsc_pnext = i->ipsc_pnext; + else { + if (i->ipsc_pnext == &ipsc_list) + ipsc_tail = NULL; + else + ipsc_tail = *(*i->ipsc_pnext)->ipsc_pnext; + } + + ipsc_stat.iscs_entries--; + KFREE(i); + } + RWLOCK_EXIT(&ipsc_rwlock); + return err; +} + + +struct ipscan *ipsc_lookup(tag) +char *tag; +{ + ipscan_t *i; + + for (i = ipsc_list; i; i = i->ipsc_next) + if (!strcmp(i->ipsc_tag, tag)) + return i; + return NULL; +} + + +int ipsc_attachfr(fr) +struct frentry *fr; +{ + ipscan_t *i; + + if (fr->fr_isctag[0]) { + READ_ENTER(&ipsc_rwlock); + i = ipsc_lookup(fr->fr_isctag); + if (i != NULL) { + ATOMIC_INC32(i->ipsc_fref); + } + RWLOCK_EXIT(&ipsc_rwlock); + if (i == NULL) + return ENOENT; + fr->fr_isc = i; + } + return 0; +} + + +int ipsc_attachis(is) +struct ipstate *is; +{ + frentry_t *fr; + ipscan_t *i; + + READ_ENTER(&ipsc_rwlock); + fr = is->is_rule; + if (fr) { + i = fr->fr_isc; + if (!i || (i != (ipscan_t *)-1)) { + is->is_isc = i; + if (i) { + ATOMIC_INC32(i->ipsc_sref); + if (i->ipsc_clen) + is->is_flags |= IS_SC_CLIENT; + else + is->is_flags |= IS_SC_MATCHC; + if (i->ipsc_slen) + is->is_flags |= IS_SC_SERVER; + else + is->is_flags |= IS_SC_MATCHS; + } else + is->is_flags |= (IS_SC_CLIENT|IS_SC_SERVER); + } + } + RWLOCK_EXIT(&ipsc_rwlock); + return 0; +} + + +int ipsc_detachfr(fr) +struct frentry *fr; +{ + ipscan_t *i; + + i = fr->fr_isc; + if (i != NULL) { + ATOMIC_DEC32(i->ipsc_fref); + } + return 0; +} + + +int ipsc_detachis(is) +struct ipstate *is; +{ + ipscan_t *i; + + READ_ENTER(&ipsc_rwlock); + if ((i = is->is_isc) && (i != (ipscan_t *)-1)) { + ATOMIC_DEC32(i->ipsc_sref); + is->is_isc = NULL; + is->is_flags &= ~(IS_SC_CLIENT|IS_SC_SERVER); + } + RWLOCK_EXIT(&ipsc_rwlock); + return 0; +} + + +/* + * 'string' compare for scanning + */ +int ipsc_matchstr(sp, str, n) +sinfo_t *sp; +char *str; +int n; +{ + char *s, *t, *up; + int i = n; + + if (i > sp->s_len) + i = sp->s_len; + up = str; + + for (s = sp->s_txt, t = sp->s_msk; i; i--, s++, t++, up++) + switch ((int)*t) + { + case '.' : + if (*s != *up) + return 1; + break; + case '?' : + if (!ISALPHA(*up) || ((*s & 0x5f) != (*up & 0x5f))) + return 1; + break; + case '*' : + break; + } + return 0; +} + + +/* + * Returns 3 if both server and client match, 2 if just server, + * 1 if just client + */ +int ipsc_matchisc(isc, is, cl, sl, maxm) +ipscan_t *isc; +ipstate_t *is; +int cl, sl, maxm[2]; +{ + int i, j, k, n, ret = 0, flags; + + flags = is->is_flags; + + /* + * If we've already matched more than what is on offer, then + * assume we have a better match already and forget this one. + */ + if (maxm != NULL) { + if (isc->ipsc_clen < maxm[0]) + return 0; + if (isc->ipsc_slen < maxm[1]) + return 0; + j = maxm[0]; + k = maxm[1]; + } else { + j = 0; + k = 0; + } + + if (!isc->ipsc_clen) + ret = 1; + else if (((flags & (IS_SC_MATCHC|IS_SC_CLIENT)) == IS_SC_CLIENT) && + cl && isc->ipsc_clen) { + i = 0; + n = MIN(cl, isc->ipsc_clen); + if ((n > 0) && (!maxm || (n >= maxm[1]))) { + if (!ipsc_matchstr(&isc->ipsc_cl, is->is_sbuf[0], n)) { + i++; + ret |= 1; + if (n > j) + j = n; + } + } + } + + if (!isc->ipsc_slen) + ret |= 2; + else if (((flags & (IS_SC_MATCHS|IS_SC_SERVER)) == IS_SC_SERVER) && + sl && isc->ipsc_slen) { + i = 0; + n = MIN(cl, isc->ipsc_slen); + if ((n > 0) && (!maxm || (n >= maxm[1]))) { + if (!ipsc_matchstr(&isc->ipsc_sl, is->is_sbuf[1], n)) { + i++; + ret |= 2; + if (n > k) + k = n; + } + } + } + + if (maxm && (ret == 3)) { + maxm[0] = j; + maxm[1] = k; + } + return ret; +} + + +int ipsc_match(is) +ipstate_t *is; +{ + int i, j, k, n, cl, sl, maxm[2]; + ipscan_t *isc, *lm; + tcpdata_t *t; + + for (cl = 0, n = is->is_smsk[0]; n & 1; n >>= 1) + cl++; + for (sl = 0, n = is->is_smsk[1]; n & 1; n >>= 1) + sl++; + + j = 0; + isc = is->is_isc; + if (isc != NULL) { + /* + * Known object to scan for. + */ + i = ipsc_matchisc(isc, is, cl, sl, NULL); + if (i & 1) { + is->is_flags |= IS_SC_MATCHC; + is->is_flags &= ~IS_SC_CLIENT; + } else if (cl >= isc->ipsc_clen) + is->is_flags &= ~IS_SC_CLIENT; + if (i & 2) { + is->is_flags |= IS_SC_MATCHS; + is->is_flags &= ~IS_SC_SERVER; + } else if (sl >= isc->ipsc_slen) + is->is_flags &= ~IS_SC_SERVER; + } else { + i = 0; + lm = NULL; + maxm[0] = 0; + maxm[1] = 0; + for (k = 0, isc = ipsc_list; isc; isc = isc->ipsc_next) { + i = ipsc_matchisc(isc, is, cl, sl, maxm); + if (i) { + /* + * We only want to remember the best match + * and the number of times we get a best + * match. + */ + if ((j == 3) && (i < 3)) + continue; + if ((i == 3) && (j != 3)) + k = 1; + else + k++; + j = i; + lm = isc; + } + } + if (k == 1) + isc = lm; + + /* + * No matches or partial matches, so reset the respective + * search flag. + */ + if (!(j & 1)) + is->is_flags &= ~IS_SC_CLIENT; + + if (!(j & 2)) + is->is_flags &= ~IS_SC_SERVER; + + /* + * If we found the best match, then set flags appropriately. + */ + if ((j == 3) && (k == 1)) { + is->is_flags &= ~(IS_SC_SERVER|IS_SC_CLIENT); + is->is_flags |= (IS_SC_MATCHS|IS_SC_MATCHC); + } + } + + /* + * If the acknowledged side of a connection has moved past the data in + * which we are interested, then reset respective flag. + */ + t = &is->is_tcp.ts_data[0]; + if (t->td_end > is->is_s0[0] + 15) + is->is_flags &= ~IS_SC_CLIENT; + + t = &is->is_tcp.ts_data[1]; + if (t->td_end > is->is_s0[1] + 15) + is->is_flags &= ~IS_SC_SERVER; + + /* + * Matching complete ? + */ + j = ISC_A_NONE; + if ((is->is_flags & IS_SC_MATCHALL) == IS_SC_MATCHALL) { + j = isc->ipsc_action; + ipsc_stat.iscs_acted++; + } else if ((is->is_isc != NULL) && + ((is->is_flags & IS_SC_MATCHALL) != IS_SC_MATCHALL) && + !(is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER))) { + /* + * Matching failed... + */ + j = isc->ipsc_else; + ipsc_stat.iscs_else++; + } + + switch (j) + { + case ISC_A_CLOSE : + /* + * If as a result of a successful match we are to + * close a connection, change the "keep state" info. + * to block packets and generate TCP RST's. + */ + is->is_pass &= ~FR_RETICMP; + is->is_pass |= FR_RETRST; + break; + default : + break; + } + + return i; +} + + +/* + * check if a packet matches what we're scanning for + */ +int ipsc_packet(fin, is) +fr_info_t *fin; +ipstate_t *is; +{ + int i, j, rv, dlen, off, thoff; + u_32_t seq, s0; + tcphdr_t *tcp; + + rv = !IP6_EQ(&fin->fin_fi.fi_src, &is->is_src); + tcp = fin->fin_dp; + seq = ntohl(tcp->th_seq); + + if (!is->is_s0[rv]) + return 1; + + /* + * check if this packet has more data that falls within the first + * 16 bytes sent in either direction. + */ + s0 = is->is_s0[rv]; + off = seq - s0; + if ((off > 15) || (off < 0)) + return 1; + thoff = TCP_OFF(tcp) << 2; + dlen = fin->fin_dlen - thoff; + if (dlen <= 0) + return 1; + if (dlen > 16) + dlen = 16; + if (off + dlen > 16) + dlen = 16 - off; + + j = 0xffff >> (16 - dlen); + i = (0xffff & j) << off; +#ifdef _KERNEL + COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_hlen + thoff, dlen, + (caddr_t)is->is_sbuf[rv] + off); +#endif + is->is_smsk[rv] |= i; + for (j = 0, i = is->is_smsk[rv]; i & 1; i >>= 1) + j++; + if (j == 0) + return 1; + + (void) ipsc_match(is); +#if 0 + /* + * There is the potential here for plain text passwords to get + * buffered and stored for some time... + */ + if (!(is->is_flags & IS_SC_CLIENT)) + bzero(is->is_sbuf[0], sizeof(is->is_sbuf[0])); + if (!(is->is_flags & IS_SC_SERVER)) + bzero(is->is_sbuf[1], sizeof(is->is_sbuf[1])); +#endif + return 0; +} + + +int fr_scan_ioctl(data, cmd, mode) +caddr_t data; +ioctlcmd_t cmd; +int mode; +{ + ipscanstat_t ipscs; + int err = 0; + + switch (cmd) + { + case SIOCADSCA : + err = ipsc_add(data); + break; + case SIOCRMSCA : + err = ipsc_delete(data); + break; + case SIOCGSCST : + bcopy((char *)&ipsc_stat, (char *)&ipscs, sizeof(ipscs)); + ipscs.iscs_list = ipsc_list; + BCOPYOUT(&ipscs, data, sizeof(ipscs)); + break; + default : + err = EINVAL; + break; + } + + return err; +} +#endif /* IPFILTER_SCAN */ diff --git a/contrib/ipfilter/ip_scan.h b/contrib/ipfilter/ip_scan.h new file mode 100644 index 000000000000..de98f9cd6b79 --- /dev/null +++ b/contrib/ipfilter/ip_scan.h @@ -0,0 +1,108 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * @(#)ip_fil.h 1.35 6/5/96 + * Id: ip_scan.h,v 2.9 2003/07/25 22:05:01 darrenr Exp + */ + +#ifndef __IP_SCAN_H__ +#define __IP_SCAN_H__ 1 + +#ifdef sun +# include +#endif + +#define IPSCAN_NAME "/dev/ipscan" +#define IPL_SCAN IPSCAN_NAME +#define ISC_TLEN 16 + + +struct fr_info; +struct frentry; +struct ip; +struct ipstate; + + +#if defined(__STDC__) || defined(__GNUC__) +# define SIOCADSCA _IOWR('r', 60, struct ipscan *) +# define SIOCRMSCA _IOWR('r', 61, struct ipscan *) +# define SIOCGSCST _IOWR('r', 62, struct ipscan *) +#else +# define SIOCADSCA _IOWR(r, 60, struct ipscan *) +# define SIOCRMSCA _IOWR(r, 61, struct ipscan *) +# define SIOCGSCST _IOWR(r, 62, struct ipscan *) +#endif + +struct action { + int act_val; /* what to do */ + struct in_addr act_ip; /* redirect IP# */ + u_short act_port; /* redirect port number */ + int act_else; /* what to do */ + struct in_addr act_eip; /* redirect IP# */ + u_short act_eport; /* redirect port number */ +}; + + +typedef struct sinfo { + char s_txt[ISC_TLEN]; /* text to match */ + char s_msk[ISC_TLEN]; /* mask of the above to check */ + int s_len; /* length of server text */ +} sinfo_t; + + +typedef struct ipscan { + struct ipscan *ipsc_next; + struct ipscan **ipsc_pnext; + char ipsc_tag[ISC_TLEN]; /* table entry protocol tag */ + sinfo_t ipsc_si[2]; /* client/server side information */ + int ipsc_hits; /* times this has been matched */ + int ipsc_active; /* # of active matches */ + int ipsc_fref; /* # of references from filter rules */ + int ipsc_sref; /* # of references from state entries */ + struct action ipsc_act; +} ipscan_t; + + +#define ipsc_cl ipsc_si[0] +#define ipsc_sl ipsc_si[1] +#define ipsc_ctxt ipsc_cl.s_txt +#define ipsc_cmsk ipsc_cl.s_msk +#define ipsc_clen ipsc_cl.s_len +#define ipsc_stxt ipsc_sl.s_txt +#define ipsc_smsk ipsc_sl.s_msk +#define ipsc_slen ipsc_sl.s_len +#define ipsc_action ipsc_act.act_val +#define ipsc_ip ipsc_act.act_ip +#define ipsc_port ipsc_act.act_port +#define ipsc_else ipsc_act.act_else +#define ipsc_eip ipsc_act.act_eip +#define ipsc_eport ipsc_act.act_eport + +#define ISC_A_NONE 0 +#define ISC_A_TRACK 1 +#define ISC_A_CLOSE 2 +#define ISC_A_REDIRECT 3 + + +typedef struct ipscanstat { + struct ipscan *iscs_list; + u_long iscs_acted; + u_long iscs_else; + int iscs_entries; +} ipscanstat_t; + + +extern int fr_scan_ioctl __P((caddr_t, ioctlcmd_t, int)); +extern int ipsc_init __P((void)); +extern int ipsc_attachis __P((struct ipstate *)); +extern int ipsc_attachfr __P((struct frentry *)); +extern int ipsc_detachis __P((struct ipstate *)); +extern int ipsc_detachfr __P((struct frentry *)); +extern int ipsc_packet __P((struct fr_info *, struct ipstate *)); +extern void fr_scanunload __P((void)); + +#endif /* __IP_SCAN_H__ */ diff --git a/contrib/ipfilter/ip_sync.c b/contrib/ipfilter/ip_sync.c new file mode 100644 index 000000000000..396bae791196 --- /dev/null +++ b/contrib/ipfilter/ip_sync.c @@ -0,0 +1,1001 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1995-1998 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#include +#include +#include +#include +#if !defined(_KERNEL) && !defined(__KERNEL__) +# include +# include +# include +# define _KERNEL +# define KERNEL +# ifdef __OpenBSD__ +struct file; +# endif +# include +# undef _KERNEL +# undef KERNEL +#else +# include +# if !defined(__SVR4) && !defined(__svr4__) +# include +# endif +#endif +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +# include +#endif +#if defined(_KERNEL) && (__FreeBSD_version >= 220000) +# include +# include +# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) +# include "opt_ipfilter.h" +# endif +#else +# include +#endif +#include +#if !defined(linux) +# include +#endif +#include +#if defined(__SVR4) || defined(__svr4__) +# include +# include +# ifdef _KERNEL +# include +# endif +# include +# include +#endif + +#include +#ifdef sun +# include +#endif +#include +#include +#include +#include +#include +#if !defined(linux) +# include +#endif +#if !defined(__hpux) && !defined(linux) +# include +#endif +#include +#include +#include "netinet/ip_compat.h" +#include +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_frag.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "netinet/ip_sync.h" +#ifdef USE_INET6 +#include +#endif +#if (__FreeBSD_version >= 300000) +# include +# if defined(_KERNEL) && !defined(IPFILTER_LKM) +# include +# include +# endif +#endif +/* END OF INCLUDES */ + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.3 2005/02/18 13:06:29 darrenr Exp"; +#endif + +#define SYNC_STATETABSZ 256 +#define SYNC_NATTABSZ 256 + +#ifdef IPFILTER_SYNC +ipfmutex_t ipf_syncadd, ipsl_mutex; +ipfrwlock_t ipf_syncstate, ipf_syncnat; +#if SOLARIS && defined(_KERNEL) +kcondvar_t ipslwait; +#endif +synclist_t *syncstatetab[SYNC_STATETABSZ]; +synclist_t *syncnattab[SYNC_NATTABSZ]; +synclogent_t synclog[SYNCLOG_SZ]; +syncupdent_t syncupd[SYNCLOG_SZ]; +u_int ipf_syncnum = 1; +u_int ipf_syncwrap = 0; +u_int sl_idx = 0, /* next available sync log entry */ + su_idx = 0, /* next available sync update entry */ + sl_tail = 0, /* next sync log entry to read */ + su_tail = 0; /* next sync update entry to read */ +int ipf_sync_debug = 0; + + +# if !defined(sparc) && !defined(__hppa) +void ipfsync_tcporder __P((int, struct tcpdata *)); +void ipfsync_natorder __P((int, struct nat *)); +void ipfsync_storder __P((int, struct ipstate *)); +# endif + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_init */ +/* Returns: int - 0 == success, -1 == failure */ +/* Parameters: Nil */ +/* */ +/* Initialise all of the locks required for the sync code and initialise */ +/* any data structures, as required. */ +/* ------------------------------------------------------------------------ */ +int ipfsync_init() +{ + RWLOCK_INIT(&ipf_syncstate, "add things to state sync table"); + RWLOCK_INIT(&ipf_syncnat, "add things to nat sync table"); + MUTEX_INIT(&ipf_syncadd, "add things to sync table"); + MUTEX_INIT(&ipsl_mutex, "add things to sync table"); +# if SOLARIS && defined(_KERNEL) + cv_init(&ipslwait, "ipsl condvar", CV_DRIVER, NULL); +# endif + + bzero((char *)syncnattab, sizeof(syncnattab)); + bzero((char *)syncstatetab, sizeof(syncstatetab)); + + return 0; +} + + +# if !defined(sparc) && !defined(__hppa) +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_tcporder */ +/* Returns: Nil */ +/* Parameters: way(I) - direction of byte order conversion. */ +/* td(IO) - pointer to data to be converted. */ +/* */ +/* Do byte swapping on values in the TCP state information structure that */ +/* need to be used at both ends by the host in their native byte order. */ +/* ------------------------------------------------------------------------ */ +void ipfsync_tcporder(way, td) +int way; +tcpdata_t *td; +{ + if (way) { + td->td_maxwin = htons(td->td_maxwin); + td->td_end = htonl(td->td_end); + td->td_maxend = htonl(td->td_maxend); + } else { + td->td_maxwin = ntohs(td->td_maxwin); + td->td_end = ntohl(td->td_end); + td->td_maxend = ntohl(td->td_maxend); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_natorder */ +/* Returns: Nil */ +/* Parameters: way(I) - direction of byte order conversion. */ +/* nat(IO) - pointer to data to be converted. */ +/* */ +/* Do byte swapping on values in the NAT data structure that need to be */ +/* used at both ends by the host in their native byte order. */ +/* ------------------------------------------------------------------------ */ +void ipfsync_natorder(way, n) +int way; +nat_t *n; +{ + if (way) { + n->nat_age = htonl(n->nat_age); + n->nat_flags = htonl(n->nat_flags); + n->nat_ipsumd = htonl(n->nat_ipsumd); + n->nat_use = htonl(n->nat_use); + n->nat_dir = htonl(n->nat_dir); + } else { + n->nat_age = ntohl(n->nat_age); + n->nat_flags = ntohl(n->nat_flags); + n->nat_ipsumd = ntohl(n->nat_ipsumd); + n->nat_use = ntohl(n->nat_use); + n->nat_dir = ntohl(n->nat_dir); + } +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_storder */ +/* Returns: Nil */ +/* Parameters: way(I) - direction of byte order conversion. */ +/* ips(IO) - pointer to data to be converted. */ +/* */ +/* Do byte swapping on values in the IP state data structure that need to */ +/* be used at both ends by the host in their native byte order. */ +/* ------------------------------------------------------------------------ */ +void ipfsync_storder(way, ips) +int way; +ipstate_t *ips; +{ + ipfsync_tcporder(way, &ips->is_tcp.ts_data[0]); + ipfsync_tcporder(way, &ips->is_tcp.ts_data[1]); + + if (way) { + ips->is_hv = htonl(ips->is_hv); + ips->is_die = htonl(ips->is_die); + ips->is_pass = htonl(ips->is_pass); + ips->is_flags = htonl(ips->is_flags); + ips->is_opt = htonl(ips->is_opt); + ips->is_optmsk = htonl(ips->is_optmsk); + ips->is_sec = htons(ips->is_sec); + ips->is_secmsk = htons(ips->is_secmsk); + ips->is_auth = htons(ips->is_auth); + ips->is_authmsk = htons(ips->is_authmsk); + ips->is_s0[0] = htonl(ips->is_s0[0]); + ips->is_s0[1] = htonl(ips->is_s0[1]); + ips->is_smsk[0] = htons(ips->is_smsk[0]); + ips->is_smsk[1] = htons(ips->is_smsk[1]); + } else { + ips->is_hv = ntohl(ips->is_hv); + ips->is_die = ntohl(ips->is_die); + ips->is_pass = ntohl(ips->is_pass); + ips->is_flags = ntohl(ips->is_flags); + ips->is_opt = ntohl(ips->is_opt); + ips->is_optmsk = ntohl(ips->is_optmsk); + ips->is_sec = ntohs(ips->is_sec); + ips->is_secmsk = ntohs(ips->is_secmsk); + ips->is_auth = ntohs(ips->is_auth); + ips->is_authmsk = ntohs(ips->is_authmsk); + ips->is_s0[0] = ntohl(ips->is_s0[0]); + ips->is_s0[1] = ntohl(ips->is_s0[1]); + ips->is_smsk[0] = ntohl(ips->is_smsk[0]); + ips->is_smsk[1] = ntohl(ips->is_smsk[1]); + } +} +# else /* !defined(sparc) && !defined(__hppa) */ +# define ipfsync_tcporder(x,y) +# define ipfsync_natorder(x,y) +# define ipfsync_storder(x,y) +# endif /* !defined(sparc) && !defined(__hppa) */ + +/* enable this for debugging */ + +# ifdef _KERNEL +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_write */ +/* Returns: int - 0 == success, else error value. */ +/* Parameters: uio(I) - pointer to information about data to write */ +/* */ +/* Moves data from user space into the kernel and uses it for updating data */ +/* structures in the state/NAT tables. */ +/* ------------------------------------------------------------------------ */ +int ipfsync_write(uio) +struct uio *uio; +{ + synchdr_t sh; + + /* + * THIS MUST BE SUFFICIENT LARGE TO STORE + * ANY POSSIBLE DATA TYPE + */ + char data[2048]; + + int err = 0; + +# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) + uio->uio_rw = UIO_WRITE; +# endif + + /* Try to get bytes */ + while (uio->uio_resid > 0) { + + if (uio->uio_resid >= sizeof(sh)) { + + err = UIOMOVE((caddr_t)&sh, sizeof(sh), UIO_WRITE, uio); + + if (err) { + if (ipf_sync_debug > 2) + printf("uiomove(header) failed: %d\n", + err); + return err; + } + + /* convert to host order */ + sh.sm_magic = ntohl(sh.sm_magic); + sh.sm_len = ntohl(sh.sm_len); + sh.sm_num = ntohl(sh.sm_num); + + if (ipf_sync_debug > 8) + printf("[%d] Read v:%d p:%d cmd:%d table:%d rev:%d len:%d magic:%x\n", + sh.sm_num, sh.sm_v, sh.sm_p, sh.sm_cmd, + sh.sm_table, sh.sm_rev, sh.sm_len, + sh.sm_magic); + + if (sh.sm_magic != SYNHDRMAGIC) { + if (ipf_sync_debug > 2) + printf("uiomove(header) invalud %s\n", + "magic"); + return EINVAL; + } + + if (sh.sm_v != 4 && sh.sm_v != 6) { + if (ipf_sync_debug > 2) + printf("uiomove(header) invalid %s\n", + "protocol"); + return EINVAL; + } + + if (sh.sm_cmd > SMC_MAXCMD) { + if (ipf_sync_debug > 2) + printf("uiomove(header) invalid %s\n", + "command"); + return EINVAL; + } + + + if (sh.sm_table > SMC_MAXTBL) { + if (ipf_sync_debug > 2) + printf("uiomove(header) invalid %s\n", + "table"); + return EINVAL; + } + + } else { + /* unsufficient data, wait until next call */ + if (ipf_sync_debug > 2) + printf("uiomove(header) insufficient data"); + return EAGAIN; + } + + + /* + * We have a header, so try to read the amount of data + * needed for the request + */ + + /* not supported */ + if (sh.sm_len == 0) { + if (ipf_sync_debug > 2) + printf("uiomove(data zero length %s\n", + "not supported"); + return EINVAL; + } + + if (uio->uio_resid >= sh.sm_len) { + + err = UIOMOVE((caddr_t)data, sh.sm_len, UIO_WRITE, uio); + + if (err) { + if (ipf_sync_debug > 2) + printf("uiomove(data) failed: %d\n", + err); + return err; + } + + if (ipf_sync_debug > 7) + printf("uiomove(data) %d bytes read\n", + sh.sm_len); + + if (sh.sm_table == SMC_STATE) + err = ipfsync_state(&sh, data); + else if (sh.sm_table == SMC_NAT) + err = ipfsync_nat(&sh, data); + if (ipf_sync_debug > 7) + printf("[%d] Finished with error %d\n", + sh.sm_num, err); + + } else { + /* insufficient data, wait until next call */ + if (ipf_sync_debug > 2) + printf("uiomove(data) %s %d bytes, got %d\n", + "insufficient data, need", + sh.sm_len, uio->uio_resid); + return EAGAIN; + } + } + + /* no more data */ + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_read */ +/* Returns: int - 0 == success, else error value. */ +/* Parameters: uio(O) - pointer to information about where to store data */ +/* */ +/* This function is called when a user program wants to read some data */ +/* for pending state/NAT updates. If no data is available, the caller is */ +/* put to sleep, pending a wakeup from the "lower half" of this code. */ +/* ------------------------------------------------------------------------ */ +int ipfsync_read(uio) +struct uio *uio; +{ + syncupdent_t *su; + synclogent_t *sl; + int err = 0; + + if ((uio->uio_resid & 3) || (uio->uio_resid < 8)) + return EINVAL; + +# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) + uio->uio_rw = UIO_READ; +# endif + + MUTEX_ENTER(&ipsl_mutex); + while ((sl_tail == sl_idx) && (su_tail == su_idx)) { +# if SOLARIS && defined(_KERNEL) + if (!cv_wait_sig(&ipslwait, &ipsl_mutex)) { + MUTEX_EXIT(&ipsl_mutex); + return EINTR; + } +# else +# ifdef __hpux + { + lock_t *l; + + l = get_sleep_lock(&sl_tail); + err = sleep(&sl_tail, PZERO+1); + spinunlock(l); + } +# else /* __hpux */ +# ifdef __osf__ + err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0, + &ipsl_mutex, MS_LOCK_SIMPLE); +# else + MUTEX_EXIT(&ipsl_mutex); + err = SLEEP(&sl_tail, "ipl sleep"); +# endif /* __osf__ */ +# endif /* __hpux */ + if (err) { + MUTEX_EXIT(&ipsl_mutex); + return err; + } +# endif /* SOLARIS */ + } + MUTEX_EXIT(&ipsl_mutex); + + READ_ENTER(&ipf_syncstate); + while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) { + sl = synclog + sl_tail++; + err = UIOMOVE((caddr_t)sl, sizeof(*sl), UIO_READ, uio); + if (err != 0) + break; + } + + while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) { + su = syncupd + su_tail; + su_tail++; + err = UIOMOVE((caddr_t)su, sizeof(*su), UIO_READ, uio); + if (err != 0) + break; + if (su->sup_hdr.sm_sl != NULL) + su->sup_hdr.sm_sl->sl_idx = -1; + } + + MUTEX_ENTER(&ipf_syncadd); + if (su_tail == su_idx) + su_tail = su_idx = 0; + if (sl_tail == sl_idx) + sl_tail = sl_idx = 0; + MUTEX_EXIT(&ipf_syncadd); + RWLOCK_EXIT(&ipf_syncstate); + return err; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_state */ +/* Returns: int - 0 == success, else error value. */ +/* Parameters: sp(I) - pointer to sync packet data header */ +/* uio(I) - pointer to user data for further information */ +/* */ +/* Updates the state table according to information passed in the sync */ +/* header. As required, more data is fetched from the uio structure but */ +/* varies depending on the contents of the sync header. This function can */ +/* create a new state entry or update one. Deletion is left to the state */ +/* structures being timed out correctly. */ +/* ------------------------------------------------------------------------ */ +int ipfsync_state(sp, data) +synchdr_t *sp; +void *data; +{ + synctcp_update_t su; + ipstate_t *is, sn; + synclist_t *sl; + frentry_t *fr; + u_int hv; + int err = 0; + + hv = sp->sm_num & (SYNC_STATETABSZ - 1); + + switch (sp->sm_cmd) + { + case SMC_CREATE : + + bcopy(data, &sn, sizeof(sn)); + KMALLOC(is, ipstate_t *); + if (is == NULL) { + err = ENOMEM; + break; + } + + KMALLOC(sl, synclist_t *); + if (sl == NULL) { + err = ENOMEM; + KFREE(is); + break; + } + + bzero((char *)is, offsetof(ipstate_t, is_die)); + bcopy((char *)&sn.is_die, (char *)&is->is_die, + sizeof(*is) - offsetof(ipstate_t, is_die)); + ipfsync_storder(0, is); + + /* + * We need to find the same rule on the slave as was used on + * the master to create this state entry. + */ + READ_ENTER(&ipf_mutex); + fr = fr_getrulen(IPL_LOGIPF, sn.is_group, sn.is_rulen); + if (fr != NULL) { + MUTEX_ENTER(&fr->fr_lock); + fr->fr_ref++; + fr->fr_statecnt++; + MUTEX_EXIT(&fr->fr_lock); + } + RWLOCK_EXIT(&ipf_mutex); + + if (ipf_sync_debug > 4) + printf("[%d] Filter rules = %p\n", sp->sm_num, fr); + + is->is_rule = fr; + is->is_sync = sl; + + sl->sl_idx = -1; + sl->sl_ips = is; + bcopy(sp, &sl->sl_hdr, sizeof(struct synchdr)); + + WRITE_ENTER(&ipf_syncstate); + WRITE_ENTER(&ipf_state); + + sl->sl_pnext = syncstatetab + hv; + sl->sl_next = syncstatetab[hv]; + if (syncstatetab[hv] != NULL) + syncstatetab[hv]->sl_pnext = &sl->sl_next; + syncstatetab[hv] = sl; + MUTEX_DOWNGRADE(&ipf_syncstate); + fr_stinsert(is, sp->sm_rev); + /* + * Do not initialise the interface pointers for the state + * entry as the full complement of interface names may not + * be present. + * + * Put this state entry on its timeout queue. + */ + /*fr_setstatequeue(is, sp->sm_rev);*/ + break; + + case SMC_UPDATE : + bcopy(data, &su, sizeof(su)); + + if (ipf_sync_debug > 4) + printf("[%d] Update age %lu state %d/%d \n", + sp->sm_num, su.stu_age, su.stu_state[0], + su.stu_state[1]); + + READ_ENTER(&ipf_syncstate); + for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) + if (sl->sl_hdr.sm_num == sp->sm_num) + break; + if (sl == NULL) { + if (ipf_sync_debug > 1) + printf("[%d] State not found - can't update\n", + sp->sm_num); + RWLOCK_EXIT(&ipf_syncstate); + err = ENOENT; + break; + } + + READ_ENTER(&ipf_state); + + if (ipf_sync_debug > 6) + printf("[%d] Data from state v:%d p:%d cmd:%d table:%d rev:%d\n", + sp->sm_num, sl->sl_hdr.sm_v, sl->sl_hdr.sm_p, + sl->sl_hdr.sm_cmd, sl->sl_hdr.sm_table, + sl->sl_hdr.sm_rev); + + is = sl->sl_ips; + + MUTEX_ENTER(&is->is_lock); + switch (sp->sm_p) + { + case IPPROTO_TCP : + /* XXX FV --- shouldn't we do ntohl/htonl???? XXX */ + is->is_send = su.stu_data[0].td_end; + is->is_maxsend = su.stu_data[0].td_maxend; + is->is_maxswin = su.stu_data[0].td_maxwin; + is->is_state[0] = su.stu_state[0]; + is->is_dend = su.stu_data[1].td_end; + is->is_maxdend = su.stu_data[1].td_maxend; + is->is_maxdwin = su.stu_data[1].td_maxwin; + is->is_state[1] = su.stu_state[1]; + break; + default : + break; + } + + if (ipf_sync_debug > 6) + printf("[%d] Setting timers for state\n", sp->sm_num); + + fr_setstatequeue(is, sp->sm_rev); + + MUTEX_EXIT(&is->is_lock); + break; + + default : + err = EINVAL; + break; + } + + if (err == 0) { + RWLOCK_EXIT(&ipf_state); + RWLOCK_EXIT(&ipf_syncstate); + } + + if (ipf_sync_debug > 6) + printf("[%d] Update completed with error %d\n", + sp->sm_num, err); + + return err; +} +# endif /* _KERNEL */ + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_del */ +/* Returns: Nil */ +/* Parameters: sl(I) - pointer to synclist object to delete */ +/* */ +/* Deletes an object from the synclist table and free's its memory. */ +/* ------------------------------------------------------------------------ */ +void ipfsync_del(sl) +synclist_t *sl; +{ + WRITE_ENTER(&ipf_syncstate); + *sl->sl_pnext = sl->sl_next; + if (sl->sl_next != NULL) + sl->sl_next->sl_pnext = sl->sl_pnext; + if (sl->sl_idx != -1) + syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL; + RWLOCK_EXIT(&ipf_syncstate); + KFREE(sl); +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_nat */ +/* Returns: int - 0 == success, else error value. */ +/* Parameters: sp(I) - pointer to sync packet data header */ +/* uio(I) - pointer to user data for further information */ +/* */ +/* Updates the NAT table according to information passed in the sync */ +/* header. As required, more data is fetched from the uio structure but */ +/* varies depending on the contents of the sync header. This function can */ +/* create a new NAT entry or update one. Deletion is left to the NAT */ +/* structures being timed out correctly. */ +/* ------------------------------------------------------------------------ */ +int ipfsync_nat(sp, data) +synchdr_t *sp; +void *data; +{ + synclogent_t sle; + syncupdent_t su; + nat_t *n, *nat; + synclist_t *sl; + u_int hv = 0; + int err; + + READ_ENTER(&ipf_syncstate); + + switch (sp->sm_cmd) + { + case SMC_CREATE : + bcopy(data, &sle, sizeof(sle)); + + KMALLOC(n, nat_t *); + if (n == NULL) { + err = ENOMEM; + break; + } + + KMALLOC(sl, synclist_t *); + if (sl == NULL) { + err = ENOMEM; + KFREE(n); + break; + } + + WRITE_ENTER(&ipf_nat); + + nat = &sle.sle_un.sleu_ipn; + bzero((char *)n, offsetof(nat_t, nat_age)); + bcopy((char *)&nat->nat_age, (char *)&n->nat_age, + sizeof(*n) - offsetof(nat_t, nat_age)); + ipfsync_natorder(0, n); + n->nat_sync = sl; + + sl->sl_idx = -1; + sl->sl_ipn = n; + sl->sl_num = ntohl(sp->sm_num); + sl->sl_pnext = syncstatetab + hv; + sl->sl_next = syncstatetab[hv]; + if (syncstatetab[hv] != NULL) + syncstatetab[hv]->sl_pnext = &sl->sl_next; + syncstatetab[hv] = sl; + nat_insert(n, sl->sl_rev); + RWLOCK_EXIT(&ipf_nat); + break; + + case SMC_UPDATE : + bcopy(data, &su, sizeof(su)); + + READ_ENTER(&ipf_syncstate); + for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) + if (sl->sl_hdr.sm_num == sp->sm_num) + break; + if (sl == NULL) { + err = ENOENT; + break; + } + + READ_ENTER(&ipf_nat); + + nat = sl->sl_ipn; + + MUTEX_ENTER(&nat->nat_lock); + fr_setnatqueue(nat, sl->sl_rev); + MUTEX_EXIT(&nat->nat_lock); + + RWLOCK_EXIT(&ipf_nat); + + break; + + default : + err = EINVAL; + break; + } + + RWLOCK_EXIT(&ipf_syncstate); + return 0; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_new */ +/* Returns: synclist_t* - NULL == failure, else pointer to new synclist */ +/* data structure. */ +/* Parameters: tab(I) - type of synclist_t to create */ +/* fin(I) - pointer to packet information */ +/* ptr(I) - pointer to owning object */ +/* */ +/* Creates a new sync table entry and notifies any sleepers that it's there */ +/* waiting to be processed. */ +/* ------------------------------------------------------------------------ */ +synclist_t *ipfsync_new(tab, fin, ptr) +int tab; +fr_info_t *fin; +void *ptr; +{ + synclist_t *sl, *ss; + synclogent_t *sle; + u_int hv, sz; + + if (sl_idx == SYNCLOG_SZ) + return NULL; + KMALLOC(sl, synclist_t *); + if (sl == NULL) + return NULL; + + MUTEX_ENTER(&ipf_syncadd); + /* + * Get a unique number for this synclist_t. The number is only meant + * to be unique for the lifetime of the structure and may be reused + * later. + */ + ipf_syncnum++; + if (ipf_syncnum == 0) { + ipf_syncnum = 1; + ipf_syncwrap = 1; + } + + hv = ipf_syncnum & (SYNC_STATETABSZ - 1); + while (ipf_syncwrap != 0) { + for (ss = syncstatetab[hv]; ss; ss = ss->sl_next) + if (ss->sl_hdr.sm_num == ipf_syncnum) + break; + if (ss == NULL) + break; + ipf_syncnum++; + hv = ipf_syncnum & (SYNC_STATETABSZ - 1); + } + /* + * Use the synch number of the object as the hash key. Should end up + * with relatively even distribution over time. + * XXX - an attacker could lunch an DoS attack, of sorts, if they are + * the only one causing new table entries by only keeping open every + * nth connection they make, where n is a value in the interval + * [0, SYNC_STATETABSZ-1]. + */ + sl->sl_pnext = syncstatetab + hv; + sl->sl_next = syncstatetab[hv]; + syncstatetab[hv] = sl; + sl->sl_num = ipf_syncnum; + MUTEX_EXIT(&ipf_syncadd); + + sl->sl_magic = htonl(SYNHDRMAGIC); + sl->sl_v = fin->fin_v; + sl->sl_p = fin->fin_p; + sl->sl_cmd = SMC_CREATE; + sl->sl_idx = -1; + sl->sl_table = tab; + sl->sl_rev = fin->fin_rev; + if (tab == SMC_STATE) { + sl->sl_ips = ptr; + sz = sizeof(*sl->sl_ips); + } else if (tab == SMC_NAT) { + sl->sl_ipn = ptr; + sz = sizeof(*sl->sl_ipn); + } else { + ptr = NULL; + sz = 0; + } + sl->sl_len = sz; + + /* + * Create the log entry to be read by a user daemon. When it has been + * finished and put on the queue, send a signal to wakeup any waiters. + */ + MUTEX_ENTER(&ipf_syncadd); + sle = synclog + sl_idx++; + bcopy((char *)&sl->sl_hdr, (char *)&sle->sle_hdr, + sizeof(sle->sle_hdr)); + sle->sle_hdr.sm_num = htonl(sle->sle_hdr.sm_num); + sle->sle_hdr.sm_len = htonl(sle->sle_hdr.sm_len); + if (ptr != NULL) { + bcopy((char *)ptr, (char *)&sle->sle_un, sz); + if (tab == SMC_STATE) { + ipfsync_storder(1, &sle->sle_un.sleu_ips); + } else if (tab == SMC_NAT) { + ipfsync_natorder(1, &sle->sle_un.sleu_ipn); + } + } + MUTEX_EXIT(&ipf_syncadd); + + MUTEX_ENTER(&ipsl_mutex); +# if SOLARIS +# ifdef _KERNEL + cv_signal(&ipslwait); +# endif + MUTEX_EXIT(&ipsl_mutex); +# else + MUTEX_EXIT(&ipsl_mutex); +# ifdef _KERNEL + wakeup(&sl_tail); +# endif +# endif + return sl; +} + + +/* ------------------------------------------------------------------------ */ +/* Function: ipfsync_update */ +/* Returns: Nil */ +/* Parameters: tab(I) - type of synclist_t to create */ +/* fin(I) - pointer to packet information */ +/* sl(I) - pointer to synchronisation object */ +/* */ +/* For outbound packets, only, create an sync update record for the user */ +/* process to read. */ +/* ------------------------------------------------------------------------ */ +void ipfsync_update(tab, fin, sl) +int tab; +fr_info_t *fin; +synclist_t *sl; +{ + synctcp_update_t *st; + syncupdent_t *slu; + ipstate_t *ips; + nat_t *nat; + + if (fin->fin_out == 0 || sl == NULL) + return; + + WRITE_ENTER(&ipf_syncstate); + MUTEX_ENTER(&ipf_syncadd); + if (sl->sl_idx == -1) { + slu = syncupd + su_idx; + sl->sl_idx = su_idx++; + bcopy((char *)&sl->sl_hdr, (char *)&slu->sup_hdr, + sizeof(slu->sup_hdr)); + slu->sup_hdr.sm_magic = htonl(SYNHDRMAGIC); + slu->sup_hdr.sm_sl = sl; + slu->sup_hdr.sm_cmd = SMC_UPDATE; + slu->sup_hdr.sm_table = tab; + slu->sup_hdr.sm_num = htonl(sl->sl_num); + slu->sup_hdr.sm_len = htonl(sizeof(struct synctcp_update)); + slu->sup_hdr.sm_rev = fin->fin_rev; +# if 0 + if (fin->fin_p == IPPROTO_TCP) { + st->stu_len[0] = 0; + st->stu_len[1] = 0; + } +# endif + } else + slu = syncupd + sl->sl_idx; + MUTEX_EXIT(&ipf_syncadd); + MUTEX_DOWNGRADE(&ipf_syncstate); + + /* + * Only TCP has complex timeouts, others just use default timeouts. + * For TCP, we only need to track the connection state and window. + */ + if (fin->fin_p == IPPROTO_TCP) { + st = &slu->sup_tcp; + if (tab == SMC_STATE) { + ips = sl->sl_ips; + st->stu_age = htonl(ips->is_die); + st->stu_data[0].td_end = ips->is_send; + st->stu_data[0].td_maxend = ips->is_maxsend; + st->stu_data[0].td_maxwin = ips->is_maxswin; + st->stu_state[0] = ips->is_state[0]; + st->stu_data[1].td_end = ips->is_dend; + st->stu_data[1].td_maxend = ips->is_maxdend; + st->stu_data[1].td_maxwin = ips->is_maxdwin; + st->stu_state[1] = ips->is_state[1]; + } else if (tab == SMC_NAT) { + nat = sl->sl_ipn; + st->stu_age = htonl(nat->nat_age); + } + } + RWLOCK_EXIT(&ipf_syncstate); + + MUTEX_ENTER(&ipsl_mutex); +# if SOLARIS +# ifdef _KERNEL + cv_signal(&ipslwait); +# endif + MUTEX_EXIT(&ipsl_mutex); +# else + MUTEX_EXIT(&ipsl_mutex); +# ifdef _KERNEL + wakeup(&sl_tail); +# endif +# endif +} + + +/* ------------------------------------------------------------------------ */ +/* Function: fr_sync_ioctl */ +/* Returns: int - 0 == success, != 0 == failure */ +/* Parameters: data(I) - pointer to ioctl data */ +/* cmd(I) - ioctl command integer */ +/* mode(I) - file mode bits used with open */ +/* */ +/* This function currently does not handle any ioctls and so just returns */ +/* EINVAL on all occasions. */ +/* ------------------------------------------------------------------------ */ +int fr_sync_ioctl(data, cmd, mode) +caddr_t data; +ioctlcmd_t cmd; +int mode; +{ + return EINVAL; +} +#endif /* IPFILTER_SYNC */ diff --git a/contrib/ipfilter/ip_sync.h b/contrib/ipfilter/ip_sync.h new file mode 100644 index 000000000000..e319a95dfcdb --- /dev/null +++ b/contrib/ipfilter/ip_sync.h @@ -0,0 +1,117 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * @(#)ip_fil.h 1.35 6/5/96 + * Id: ip_sync.h,v 2.11.2.2 2004/11/04 19:29:07 darrenr Exp + */ + +#ifndef __IP_SYNC_H__ +#define __IP_SYNC_H__ + +typedef struct synchdr { + u_32_t sm_magic; /* magic */ + u_char sm_v; /* version: 4,6 */ + u_char sm_p; /* protocol */ + u_char sm_cmd; /* command */ + u_char sm_table; /* NAT, STATE, etc */ + u_int sm_num; /* table entry number */ + int sm_rev; /* forward/reverse */ + int sm_len; /* length of the data section */ + struct synclist *sm_sl; /* back pointer to parent */ +} synchdr_t; + + +#define SYNHDRMAGIC 0x0FF51DE5 + +/* + * Commands + * No delete required as expirey will take care of that! + */ +#define SMC_CREATE 0 /* pass ipstate_t after synchdr_t */ +#define SMC_UPDATE 1 +#define SMC_MAXCMD 1 + +/* + * Tables + */ +#define SMC_NAT 0 +#define SMC_STATE 1 +#define SMC_MAXTBL 1 + + +/* + * Only TCP requires "more" information than just a reference to the entry + * for which an update is being made. + */ +typedef struct synctcp_update { + u_long stu_age; + tcpdata_t stu_data[2]; + int stu_state[2]; +} synctcp_update_t; + + +typedef struct synclist { + struct synclist *sl_next; + struct synclist **sl_pnext; + int sl_idx; /* update index */ + struct synchdr sl_hdr; + union { + struct ipstate *slu_ips; + struct nat *slu_ipn; + void *slu_ptr; + } sl_un; +} synclist_t; + +#define sl_ptr sl_un.slu_ptr +#define sl_ips sl_un.slu_ips +#define sl_ipn sl_un.slu_ipn +#define sl_magic sl_hdr.sm_magic +#define sl_v sl_hdr.sm_v +#define sl_p sl_hdr.sm_p +#define sl_cmd sl_hdr.sm_cmd +#define sl_rev sl_hdr.sm_rev +#define sl_table sl_hdr.sm_table +#define sl_num sl_hdr.sm_num +#define sl_len sl_hdr.sm_len + +/* + * NOTE: SYNCLOG_SZ is defined *low*. It should be the next power of two + * up for whatever number of packets per second you expect to see. Be + * warned: this index's a table of large elements (upto 272 bytes in size + * each), and thus a size of 8192, for example, results in a 2MB table. + * The lesson here is not to use small machines for running fast firewalls + * (100BaseT) in sync, where you might have upwards of 10k pps. + */ +#define SYNCLOG_SZ 256 + +typedef struct synclogent { + struct synchdr sle_hdr; + union { + struct ipstate sleu_ips; + struct nat sleu_ipn; + } sle_un; +} synclogent_t; + +typedef struct syncupdent { /* 28 or 32 bytes */ + struct synchdr sup_hdr; + struct synctcp_update sup_tcp; +} syncupdent_t; + +extern synclogent_t synclog[SYNCLOG_SZ]; + + +extern int fr_sync_ioctl __P((caddr_t, ioctlcmd_t, int)); +extern synclist_t *ipfsync_new __P((int, fr_info_t *, void *)); +extern void ipfsync_del __P((synclist_t *)); +extern void ipfsync_update __P((int, fr_info_t *, synclist_t *)); +extern int ipfsync_init __P((void)); +extern int ipfsync_nat __P((synchdr_t *sp, void *data)); +extern int ipfsync_state __P((synchdr_t *sp, void *data)); +extern int ipfsync_read __P((struct uio *uio)); +extern int ipfsync_write __P((struct uio *uio)); + +#endif /* IP_SYNC */ diff --git a/contrib/ipfilter/ipf.h b/contrib/ipfilter/ipf.h index 9260d03f0a53..1398c05f7cd7 100644 --- a/contrib/ipfilter/ipf.h +++ b/contrib/ipfilter/ipf.h @@ -1,72 +1,124 @@ +/* $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. * * @(#)ipf.h 1.12 6/5/96 - * $Id: ipf.h,v 2.9.2.7 2003/05/15 17:45:33 darrenr Exp $ + * Id: ipf.h,v 2.71.2.6 2005/02/21 05:05:29 darrenr Exp */ #ifndef __IPF_H__ #define __IPF_H__ -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) +#if defined(__osf__) +# define radix_mask ipf_radix_mask +# define radix_node ipf_radix_node +# define radix_node_head ipf_radix_node_head #endif -#define OPT_REMOVE 0x000001 -#define OPT_DEBUG 0x000002 -#define OPT_OUTQUE FR_OUTQUE /* 0x00004 */ -#define OPT_INQUE FR_INQUE /* 0x00008 */ -#define OPT_LOG FR_LOG /* 0x00010 */ -#define OPT_SHOWLIST 0x000020 -#define OPT_VERBOSE 0x000040 -#define OPT_DONOTHING 0x000080 -#define OPT_HITS 0x000100 -#define OPT_BRIEF 0x000200 -#define OPT_ACCNT FR_ACCOUNT /* 0x0400 */ -#define OPT_FRSTATES FR_KEEPFRAG /* 0x0800 */ -#define OPT_IPSTATES FR_KEEPSTATE /* 0x1000 */ -#define OPT_INACTIVE FR_INACTIVE /* 0x2000 */ -#define OPT_SHOWLINENO 0x004000 -#define OPT_PRINTFR 0x008000 -#define OPT_ZERORULEST 0x010000 -#define OPT_SAVEOUT 0x020000 -#define OPT_AUTHSTATS 0x040000 -#define OPT_RAW 0x080000 -#define OPT_NAT 0x100000 -#define OPT_GROUPS 0x200000 -#define OPT_STATETOP 0x400000 -#define OPT_FLUSH 0x800000 -#define OPT_CLEAR 0x1000000 -#define OPT_HEX 0x2000000 -#define OPT_NODO 0x80000000 -#define OPT_STAT OPT_FRSTATES -#define OPT_LIST OPT_SHOWLIST +#include +#include +#include +/* + * This is a workaround for troubles on FreeBSD, HPUX, OpenBSD. + * Needed here because on some systems gets included by things + * like + */ +#ifndef _KERNEL +# define ADD_KERNEL +# define _KERNEL +# define KERNEL +#endif +#ifdef __OpenBSD__ +struct file; +#endif +#include +#ifdef ADD_KERNEL +# undef _KERNEL +# undef KERNEL +#endif +#include +#include +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#include +#include +#include +#include +#ifndef TCP_PAWS_IDLE /* IRIX */ +# include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +#if !defined(__SVR4) && !defined(__svr4__) && defined(sun) +# include +#endif +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_frag.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "netinet/ip_auth.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" +#include "netinet/ip_scan.h" +#include "netinet/ip_htable.h" +#include "netinet/ip_sync.h" + +#include "opts.h" #ifndef __P -# ifdef __STDC__ +# ifdef __STDC__ # define __P(x) x # else # define __P(x) () # endif #endif - -struct ipstate; -struct frpcmp; -struct ipnat; -struct nat; - -#ifdef ultrix -extern char *strdup __P((char *)); +#ifndef __STDC__ +# undef const +# define const #endif -extern struct frentry *parse __P((char *, int, int *)); +#ifndef U_32_T +# define U_32_T 1 +# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \ + defined(__sgi) +typedef u_int32_t u_32_t; +# else +# if defined(__alpha__) || defined(__alpha) || defined(_LP64) +typedef unsigned int u_32_t; +# else +# if SOLARIS2 >= 6 +typedef uint32_t u_32_t; +# else +typedef unsigned int u_32_t; +# endif +# endif +# endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */ +#endif /* U_32_T */ -extern void printfr __P((struct frentry *)); -extern void binprint __P((struct frentry *)), initparse __P((void)); -extern int portnum __P((char *, u_short *, int)); +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + +#define MAX_ICMPCODE 16 +#define MAX_ICMPTYPE 19 struct ipopt_names { @@ -77,47 +129,178 @@ struct ipopt_names { }; -extern char *proto; +typedef struct alist_s { + struct alist_s *al_next; + int al_not; + i6addr_t al_i6addr; + i6addr_t al_i6mask; +} alist_t; + +#define al_addr al_i6addr.in4_addr +#define al_mask al_i6mask.in4_addr +#define al_1 al_addr +#define al_2 al_mask + + +typedef struct { + u_short fb_c; + u_char fb_t; + u_char fb_f; + u_32_t fb_k; +} fakebpf_t; + + +#if defined(__NetBSD__) || defined(__OpenBSD__) || \ + (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \ + SOLARIS || defined(__sgi) || defined(__osf__) || defined(linux) +# include +typedef int (* ioctlfunc_t) __P((int, ioctlcmd_t, ...)); +#else +typedef int (* ioctlfunc_t) __P((dev_t, ioctlcmd_t, void *)); +#endif +typedef void (* addfunc_t) __P((int, ioctlfunc_t, void *)); +typedef int (* copyfunc_t) __P((void *, void *, size_t)); + + +/* + * SunOS4 + */ +#if defined(sun) && !defined(__SVR4) && !defined(__svr4__) +extern int ioctl __P((int, int, void *)); +#endif + +extern char thishost[]; extern char flagset[]; extern u_char flags[]; +extern struct ipopt_names ionames[]; +extern struct ipopt_names secclass[]; +extern char *icmpcodes[MAX_ICMPCODE + 1]; +extern char *icmptypes[MAX_ICMPTYPE + 1]; +extern int use_inet6; +extern int lineNum; +extern struct ipopt_names v6ionames[]; -extern u_char tcp_flags __P((char *, u_char *, int)); -extern int countbits __P((u_32_t)); -extern int ratoi __P((char *, int *, int, int)); -extern int ratoui __P((char *, u_int *, u_int, u_int)); -extern int hostmask __P((char ***, u_32_t *, u_32_t *, u_short *, int *, - u_short *, int)); -extern int ports __P((char ***, u_short *, int *, u_short *, int)); -extern char *portname __P((int, int)); -extern u_32_t buildopts __P((char *, char *, int)); -extern int genmask __P((char *, u_32_t *)); -extern int hostnum __P((u_32_t *, char *, int)); -extern u_32_t optname __P((char ***, u_short *, int)); -extern void printpacket __P((ip_t *)); -extern void printpacket6 __P((ip_t *)); -extern void printportcmp __P((int, struct frpcmp *)); -extern void printhostmask __P((int, u_32_t *, u_32_t *)); -extern void printbuf __P((char *, int, int)); -extern char *hostname __P((int, void *)); -extern struct ipstate *printstate __P((struct ipstate *, int)); -extern void printnat __P((struct ipnat *, int)); -extern void printactivenat __P((struct nat *, int)); + +extern int addicmp __P((char ***, struct frentry *, int)); +extern int addipopt __P((char *, struct ipopt_names *, int, char *)); +extern int addkeep __P((char ***, struct frentry *, int)); +extern int bcopywrap __P((void *, void *, size_t)); +extern void binprint __P((void *, size_t)); +extern void initparse __P((void)); +extern u_32_t buildopts __P((char *, char *, int)); +extern int checkrev __P((char *)); +extern int count6bits __P((u_32_t *)); +extern int count4bits __P((u_32_t)); +extern int extras __P((char ***, struct frentry *, int)); +extern char *fac_toname __P((int)); +extern int fac_findname __P((char *)); +extern void fill6bits __P((int, u_int *)); +extern int gethost __P((char *, u_32_t *)); +extern int getport __P((struct frentry *, char *, u_short *)); +extern int getportproto __P((char *, int)); +extern int getproto __P((char *)); +extern char *getline __P((char *, size_t, FILE *, int *)); +extern int genmask __P((char *, u_32_t *)); +extern char *getnattype __P((struct ipnat *)); +extern char *getsumd __P((u_32_t)); +extern u_32_t getoptbyname __P((char *)); +extern u_32_t getoptbyvalue __P((int)); +extern u_32_t getv6optbyname __P((char *)); +extern u_32_t getv6optbyvalue __P((int)); +extern void hexdump __P((FILE *, void *, int, int)); +extern int hostmask __P((char ***, char *, char *, u_32_t *, u_32_t *, int)); +extern int hostnum __P((u_32_t *, char *, int, char *)); +extern int icmpcode __P((char *)); +extern int icmpidnum __P((char *, u_short *, int)); +extern void initparse __P((void)); +extern void ipf_dotuning __P((int, char *, ioctlfunc_t)); +extern void ipf_addrule __P((int, ioctlfunc_t, void *)); +extern int ipf_parsefile __P((int, addfunc_t, ioctlfunc_t *, char *)); +extern int ipf_parsesome __P((int, addfunc_t, ioctlfunc_t *, FILE *)); +extern int ipmon_parsefile __P((char *)); +extern int ipmon_parsesome __P((FILE *)); +extern void ipnat_addrule __P((int, ioctlfunc_t, void *)); +extern int ipnat_parsefile __P((int, addfunc_t, ioctlfunc_t, char *)); +extern int ipnat_parsesome __P((int, addfunc_t, ioctlfunc_t, FILE *)); +extern int ippool_parsefile __P((int, char *, ioctlfunc_t)); +extern int ippool_parsesome __P((int, FILE *, ioctlfunc_t)); +extern int kmemcpywrap __P((void *, void *, size_t)); +extern char *kvatoname __P((ipfunc_t, ioctlfunc_t)); +extern int load_hash __P((struct iphtable_s *, struct iphtent_s *, + ioctlfunc_t)); +extern int load_hashnode __P((int, char *, struct iphtent_s *, ioctlfunc_t)); +extern int load_pool __P((struct ip_pool_s *list, ioctlfunc_t)); +extern int load_poolnode __P((int, char *, ip_pool_node_t *, ioctlfunc_t)); +extern int loglevel __P((char **, u_int *, int)); +extern alist_t *make_range __P((int, struct in_addr, struct in_addr)); +extern ipfunc_t nametokva __P((char *, ioctlfunc_t)); +extern ipnat_t *natparse __P((char *, int)); +extern void natparsefile __P((int, char *, int)); +extern void nat_setgroupmap __P((struct ipnat *)); +extern int ntomask __P((int, int, u_32_t *)); +extern u_32_t optname __P((char ***, u_short *, int)); +extern struct frentry *parse __P((char *, int)); +extern char *portname __P((int, int)); +extern int portnum __P((char *, char *, u_short *, int)); +extern int ports __P((char ***, char *, u_short *, int *, u_short *, int)); +extern int pri_findname __P((char *)); +extern char *pri_toname __P((int)); +extern void print_toif __P((char *, struct frdest *)); +extern void printaps __P((ap_session_t *, int)); +extern void printbuf __P((char *, int, int)); +extern void printfr __P((struct frentry *, ioctlfunc_t)); +extern void printtunable __P((ipftune_t *)); +extern struct iphtable_s *printhash __P((struct iphtable_s *, copyfunc_t, + char *, int)); +extern struct iphtent_s *printhashnode __P((struct iphtable_s *, + struct iphtent_s *, + copyfunc_t, int)); +extern void printhostmask __P((int, u_32_t *, u_32_t *)); +extern void printip __P((u_32_t *)); +extern void printlog __P((struct frentry *)); +extern void printlookup __P((i6addr_t *addr, i6addr_t *mask)); +extern void printmask __P((u_32_t *)); +extern void printpacket __P((struct ip *)); +extern void printpacket6 __P((struct ip *)); +extern struct ip_pool_s *printpool __P((struct ip_pool_s *, copyfunc_t, + char *, int)); +extern struct ip_pool_node *printpoolnode __P((struct ip_pool_node *, int)); +extern void printportcmp __P((int, struct frpcmp *)); +extern void optprint __P((u_short *, u_long, u_long)); +#ifdef USE_INET6 +extern void optprintv6 __P((u_short *, u_long, u_long)); +#endif +extern int ratoi __P((char *, int *, int, int)); +extern int ratoui __P((char *, u_int *, u_int, u_int)); +extern int remove_hash __P((struct iphtable_s *, ioctlfunc_t)); +extern int remove_hashnode __P((int, char *, struct iphtent_s *, ioctlfunc_t)); +extern int remove_pool __P((ip_pool_t *, ioctlfunc_t)); +extern int remove_poolnode __P((int, char *, ip_pool_node_t *, ioctlfunc_t)); +extern u_char tcp_flags __P((char *, u_char *, int)); +extern u_char tcpflags __P((char *)); +extern int to_interface __P((struct frdest *, char *, int)); +extern void printc __P((struct frentry *)); +extern void printC __P((int)); +extern void emit __P((int, int, void *, struct frentry *)); +extern u_char secbit __P((int)); +extern u_char seclevel __P((char *)); +extern void printfraginfo __P((char *, struct ipfr *)); +extern void printifname __P((char *, char *, void *)); +extern char *hostname __P((int, void *)); +extern struct ipstate *printstate __P((struct ipstate *, int, u_long)); +extern void printsbuf __P((char *)); +extern void printnat __P((struct ipnat *, int)); +extern void printactivenat __P((struct nat *, int)); +extern void printhostmap __P((struct hostmap *, u_int)); +extern void printpacket __P((struct ip *)); + +extern void set_variable __P((char *, char *)); +extern char *get_variable __P((char *, char **, int)); +extern void resetlexer __P((void)); #if SOLARIS -extern int inet_aton __P((const char *, struct in_addr *)); -extern int gethostname __P((char *, int )); -extern void sync __P((void)); -#endif - -#if defined(sun) && !SOLARIS -# define STRERROR(x) sys_errlist[x] -extern char *sys_errlist[]; -#else -# define STRERROR(x) strerror(x) -#endif - -#ifndef MIN -#define MIN(a,b) ((a) > (b) ? (b) : (a)) +extern int gethostname __P((char *, int )); +extern void sync __P((void)); #endif #endif /* __IPF_H__ */ diff --git a/contrib/ipfilter/iplang/.cvsignore b/contrib/ipfilter/iplang/.cvsignore new file mode 100644 index 000000000000..68b5b4e4e985 --- /dev/null +++ b/contrib/ipfilter/iplang/.cvsignore @@ -0,0 +1,9 @@ +y.tab.h +y.output +lex.yy.c +y.tab.c +y.tab.o +lex.yy.o +iplang_y.output +iplang_y.tab.c +iplang_y.tab.h diff --git a/contrib/ipfilter/iplang/Makefile b/contrib/ipfilter/iplang/Makefile index f97bf1901307..5b53e9a43609 100644 --- a/contrib/ipfilter/iplang/Makefile +++ b/contrib/ipfilter/iplang/Makefile @@ -1,36 +1,31 @@ # -# 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. # #CC=gcc -Wuninitialized -Wstrict-prototypes -Werror -O CFLAGS=-I.. -all: $(DESTDIR)/y.tab.o $(DESTDIR)/lex.yy.o +all: $(DESTDIR)/iplang_y.o $(DESTDIR)/iplang_l.o -$(DESTDIR)/y.tab.o: $(DESTDIR)/y.tab.c - $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/y.tab.c -o $@ +$(DESTDIR)/iplang_y.o: $(DESTDIR)/iplang_y.c + $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/iplang_y.c -o $@ -$(DESTDIR)/$(OBJ)/y.tab.o: $(DESTDIR)/y.tab.c - $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/y.tab.c -o $@ +$(DESTDIR)/iplang_l.o: $(DESTDIR)/iplang_l.c + $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/iplang_l.c -o $@ -$(DESTDIR)/lex.yy.o: $(DESTDIR)/lex.yy.c - $(CC) $(DEBUG) -I. -I.. -I$(DESTDIR) -I../ipsend $(CFLAGS) $(LINUX) -c $(DESTDIR)/lex.yy.c -o $@ +iplang_y.o: iplang_y.c + $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c $< -o $@ -y.tab.o: y.tab.c - $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c y.tab.c -o $@ +iplang_l.o: iplang_l.c + $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c $< -o $@ -lex.yy.o: lex.yy.c - $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c lex.yy.c -o $@ - -$(DESTDIR)/lex.yy.c: iplang_l.l $(DESTDIR)/y.tab.h +$(DESTDIR)/iplang_l.c: iplang_l.l $(DESTDIR)/iplang_y.h lex iplang_l.l - mv lex.yy.c $(DESTDIR) + mv lex.yy.c $(DESTDIR)/iplang_l.c -$(DESTDIR)/y.tab.c $(DESTDIR)/y.tab.h: iplang_y.y +$(DESTDIR)/iplang_y.c $(DESTDIR)/iplang_y.h: iplang_y.y yacc -d iplang_y.y - mv y.tab.c $(DESTDIR) - mv y.tab.h $(DESTDIR) + mv y.tab.c $(DESTDIR)/iplang_y.c + mv y.tab.h $(DESTDIR)/iplang_y.h clean: /bin/rm -f *.o lex.yy.c y.tab.c y.tab.h diff --git a/contrib/ipfilter/iplang/iplang.h b/contrib/ipfilter/iplang/iplang.h index f36a3843c0aa..675897b8419d 100644 --- a/contrib/ipfilter/iplang/iplang.h +++ b/contrib/ipfilter/iplang/iplang.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1997-1998 by Darren Reed. * diff --git a/contrib/ipfilter/iplang/iplang_l.l b/contrib/ipfilter/iplang/iplang_l.l index cc317818c169..0a97ec94d4bf 100644 --- a/contrib/ipfilter/iplang/iplang_l.l +++ b/contrib/ipfilter/iplang/iplang_l.l @@ -1,12 +1,12 @@ +/* $NetBSD$ */ + %{ /* * Copyright (C) 1997-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. * - * $Id: iplang_l.l,v 2.2.2.1 2003/07/28 01:15:59 darrenr Exp $ + * Id: iplang_l.l,v 2.8 2003/07/28 01:15:31 darrenr Exp */ #include #include @@ -17,8 +17,7 @@ #include #include #include -#include "y.tab.h" -#include "ip_compat.h" +#include "iplang_y.h" #include "ipf.h" #ifndef __P @@ -43,13 +42,13 @@ int save_token __P((void)); void swallow __P((void)); int yylex __P((void)); -struct wordtab { +struct lwordtab { char *word; int state; int next; }; -struct wordtab words[] = { +struct lwordtab words[] = { { "interface", IL_INTERFACE, -1 }, { "iface", IL_INTERFACE, -1 }, { "name", IL_IFNAME, IL_TOKEN }, @@ -217,7 +216,7 @@ void pop_proto() int save_token() { - yylval.str = strdup(yytext); + yylval.str = strdup((char *)yytext); return IL_TOKEN; } @@ -225,7 +224,7 @@ int save_token() int next_item(nstate) int nstate; { - struct wordtab *wt; + struct lwordtab *wt; if (opts & OPT_DEBUG) printf("text=[%s] id=%d next=%d\n", yytext, nstate, next); @@ -236,13 +235,13 @@ int nstate; token++; for (wt = words; wt->word; wt++) - if (!strcasecmp(wt->word, yytext)) + if (!strcasecmp(wt->word, (char *)yytext)) return next_state(wt->state, wt->next); if (opts & OPT_DEBUG) printf("unknown keyword=[%s]\n", yytext); next = -1; if (nstate == IL_NUMBER) - yylval.num = atoi(yytext); + yylval.num = atoi((char *)yytext); token++; return nstate; } diff --git a/contrib/ipfilter/ipmon.h b/contrib/ipfilter/ipmon.h new file mode 100644 index 000000000000..a2408367e729 --- /dev/null +++ b/contrib/ipfilter/ipmon.h @@ -0,0 +1,96 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * @(#)ip_fil.h 1.35 6/5/96 + * Id: ipmon.h,v 2.8 2003/07/25 22:16:20 darrenr Exp + */ + + +typedef struct ipmon_action { + struct ipmon_action *ac_next; + int ac_mflag; /* collection of things to compare */ + int ac_dflag; /* flags to compliment the doing fields */ + int ac_syslog; /* = 1 to syslog rules. */ + char *ac_savefile; /* filename to save log records to */ + FILE *ac_savefp; + int ac_direction; + char ac_group[FR_GROUPLEN]; + char ac_nattag[16]; + u_32_t ac_logtag; + int ac_type; /* nat/state/ipf */ + int ac_proto; + int ac_rule; + int ac_packet; + int ac_second; + int ac_result; + u_32_t ac_sip; + u_32_t ac_smsk; + u_32_t ac_dip; + u_32_t ac_dmsk; + u_short ac_sport; + u_short ac_dport; + char *ac_exec; /* execute argument */ + char *ac_run; /* actual command that gets run */ + char *ac_iface; + /* + * used with ac_packet/ac_second + */ + struct timeval ac_last; + int ac_pktcnt; +} ipmon_action_t; + +#define ac_lastsec ac_last.tv_sec +#define ac_lastusec ac_last.tv_usec + +/* + * Flags indicating what fields to do matching upon (ac_mflag). + */ +#define IPMAC_DIRECTION 0x0001 +#define IPMAC_DSTIP 0x0002 +#define IPMAC_DSTPORT 0x0004 +#define IPMAC_EVERY 0x0008 +#define IPMAC_GROUP 0x0010 +#define IPMAC_INTERFACE 0x0020 +#define IPMAC_LOGTAG 0x0040 +#define IPMAC_NATTAG 0x0080 +#define IPMAC_PROTOCOL 0x0100 +#define IPMAC_RESULT 0x0200 +#define IPMAC_RULE 0x0400 +#define IPMAC_SRCIP 0x0800 +#define IPMAC_SRCPORT 0x1000 +#define IPMAC_TYPE 0x2000 +#define IPMAC_WITH 0x4000 + +#define IPMR_BLOCK 1 +#define IPMR_PASS 2 +#define IPMR_NOMATCH 3 +#define IPMR_LOG 4 + +#define IPMDO_SAVERAW 0x0001 + +#define OPT_SYSLOG 0x001 +#define OPT_RESOLVE 0x002 +#define OPT_HEXBODY 0x004 +#define OPT_VERBOSE 0x008 +#define OPT_HEXHDR 0x010 +#define OPT_TAIL 0x020 +#define OPT_NAT 0x080 +#define OPT_STATE 0x100 +#define OPT_FILTER 0x200 +#define OPT_PORTNUM 0x400 +#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) + +#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) + +#ifndef LOGFAC +#define LOGFAC LOG_LOCAL0 +#endif + +extern int load_config __P((char *)); +extern void dumphex __P((FILE *, int, char *, int)); +extern int check_action __P((char *, char *, int, int)); +extern char *getword __P((int)); diff --git a/contrib/ipfilter/ipsd/Celler/ip_compat.h b/contrib/ipfilter/ipsd/Celler/ip_compat.h index a911fd83c3f3..8b43cb94adf7 100644 --- a/contrib/ipfilter/ipsd/Celler/ip_compat.h +++ b/contrib/ipfilter/ipsd/Celler/ip_compat.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * (C)opyright 1995 by Darren Reed. * diff --git a/contrib/ipfilter/ipsd/Makefile b/contrib/ipfilter/ipsd/Makefile index b9ad044619de..0f3ce08ba229 100644 --- a/contrib/ipfilter/ipsd/Makefile +++ b/contrib/ipfilter/ipsd/Makefile @@ -1,9 +1,7 @@ # # 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. # OBJS=ipsd.o BINDEST=/usr/local/bin diff --git a/contrib/ipfilter/ipsd/ipsd.c b/contrib/ipfilter/ipsd/ipsd.c index 261ad89985c1..3d9ea4cdf568 100644 --- a/contrib/ipfilter/ipsd/ipsd.c +++ b/contrib/ipfilter/ipsd/ipsd.c @@ -1,11 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1995-1998 Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * The author of this software makes no garuntee about the - * performance of this package or its suitability to fulfill any purpose. - * */ #include #include @@ -35,7 +34,7 @@ #ifndef lint static const char sccsid[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsd.c,v 2.1.4.1 2001/06/26 10:43:21 darrenr Exp $"; +static const char rcsid[] = "@(#)Id: ipsd.c,v 2.2 2001/06/09 17:09:25 darrenr Exp"; #endif extern char *optarg; diff --git a/contrib/ipfilter/ipsd/ipsd.h b/contrib/ipfilter/ipsd/ipsd.h index a8f58c33f781..48f591101b50 100644 --- a/contrib/ipfilter/ipsd/ipsd.h +++ b/contrib/ipfilter/ipsd/ipsd.h @@ -1,11 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1995-1998 Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * The author of this software makes no garuntee about the - * performance of this package or its suitability to fulfill any purpose. - * * @(#)ipsd.h 1.3 12/3/95 */ diff --git a/contrib/ipfilter/ipsd/ipsdr.c b/contrib/ipfilter/ipsd/ipsdr.c index 298f655944c9..4689cbad83e7 100644 --- a/contrib/ipfilter/ipsd/ipsdr.c +++ b/contrib/ipfilter/ipsd/ipsdr.c @@ -1,11 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1995-1998 Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * The author of this software makes no garuntee about the - * performance of this package or its suitability to fulfill any purpose. - * */ #include #include @@ -36,7 +35,7 @@ #ifndef lint static const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.1.4.1 2001/06/26 10:43:21 darrenr Exp $"; +static const char rcsid[] = "@(#)Id: ipsdr.c,v 2.2 2001/06/09 17:09:25 darrenr Exp"; #endif extern char *optarg; diff --git a/contrib/ipfilter/ipsd/linux.h b/contrib/ipfilter/ipsd/linux.h index d9606cbba15d..2fadfcfb2529 100644 --- a/contrib/ipfilter/ipsd/linux.h +++ b/contrib/ipfilter/ipsd/linux.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1997-1998 by Darren Reed. * diff --git a/contrib/ipfilter/ipsd/sbpf.c b/contrib/ipfilter/ipsd/sbpf.c index 97bb4ce0ff3a..29a72008ab84 100644 --- a/contrib/ipfilter/ipsd/sbpf.c +++ b/contrib/ipfilter/ipsd/sbpf.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * (C)opyright 1995-1998 Darren Reed. (from tcplog) * diff --git a/contrib/ipfilter/ipsd/sdlpi.c b/contrib/ipfilter/ipsd/sdlpi.c index c08fe6977988..289ad2f46804 100644 --- a/contrib/ipfilter/ipsd/sdlpi.c +++ b/contrib/ipfilter/ipsd/sdlpi.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * @@ -158,7 +160,7 @@ int tout; (void) sprintf(devname, "/dev/%s", device); s = devname + 5; - while (*s && !isdigit(*s)) + while (*s && !ISDIGIT(*s)) s++; if (!*s) { diff --git a/contrib/ipfilter/ipsd/slinux.c b/contrib/ipfilter/ipsd/slinux.c index 2c5aa97d2e2a..3b786b04b88c 100644 --- a/contrib/ipfilter/ipsd/slinux.c +++ b/contrib/ipfilter/ipsd/slinux.c @@ -1,11 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. * - * The author of this software makes no garuntee about the - * performance of this package or its suitability to fulfill any purpose. - * */ #include diff --git a/contrib/ipfilter/ipsd/snit.c b/contrib/ipfilter/ipsd/snit.c index ec7178f1f806..8f250260c33f 100644 --- a/contrib/ipfilter/ipsd/snit.c +++ b/contrib/ipfilter/ipsd/snit.c @@ -1,11 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. * - * The author of this software makes no garuntee about the - * performance of this package or its suitability to fulfill any purpose. - * */ #include diff --git a/contrib/ipfilter/ipsend/.OLD/ip_compat.h b/contrib/ipfilter/ipsend/.OLD/ip_compat.h index c38fa59ed3c7..3b62be1dff3e 100644 --- a/contrib/ipfilter/ipsend/.OLD/ip_compat.h +++ b/contrib/ipfilter/ipsend/.OLD/ip_compat.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * (C)opyright 1995 by Darren Reed. * diff --git a/contrib/ipfilter/ipsend/.cvsignore b/contrib/ipfilter/ipsend/.cvsignore new file mode 100644 index 000000000000..b7aea24eb881 --- /dev/null +++ b/contrib/ipfilter/ipsend/.cvsignore @@ -0,0 +1,3 @@ +ipsend +ipresend +iptest diff --git a/contrib/ipfilter/ipsend/44arp.c b/contrib/ipfilter/ipsend/44arp.c index de9f4d9ce703..420635516ebf 100644 --- a/contrib/ipfilter/ipsend/44arp.c +++ b/contrib/ipfilter/ipsend/44arp.c @@ -1,33 +1,37 @@ +/* $NetBSD$ */ + /* * Based upon 4.4BSD's /usr/sbin/arp */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include #include #include #include #include #include +#if __FreeBSD_version >= 300000 +# include +#endif #include #include +#if defined(__FreeBSD__) +# include "radix_ipf.h" +#endif #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif #include "ipsend.h" #include "iplang/iplang.h" @@ -37,7 +41,7 @@ * its IP address in address * (4 bytes) */ -int resolve(host, address) +int resolve(host, address) char *host, *address; { struct hostent *hp; @@ -74,6 +78,9 @@ char *addr, *eaddr; return 0; #endif + if (!addr) + return -1; + mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; @@ -101,8 +108,8 @@ char *addr, *eaddr; rtm = (struct rt_msghdr *)next; sin = (struct sockaddr_inarp *)(rtm + 1); sdl = (struct sockaddr_dl *)(sin + 1); - if (addr && !bcmp(addr, (char *)&sin->sin_addr, - sizeof(struct in_addr))) + if (!bcmp(addr, (char *)&sin->sin_addr, + sizeof(struct in_addr))) { bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen); return 0; diff --git a/contrib/ipfilter/ipsend/Makefile b/contrib/ipfilter/ipsend/Makefile index bb8000f5389f..ed3a51e45370 100644 --- a/contrib/ipfilter/ipsend/Makefile +++ b/contrib/ipfilter/ipsend/Makefile @@ -1,9 +1,7 @@ # # 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. # IPFT=ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o opt.o OBJS=ipsend.o ip.o ipsopt.o y.tab.o lex.yy.o @@ -134,6 +132,14 @@ hpux9 : make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \ CFLAGS="$(CFLAGS)" "LIBS=" +hpux11 : + make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \ + CFLAGS="$(CFLAGS) -DIPSEND" "LIBS=" + make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \ + CFLAGS="$(CFLAGS)" "LIBS=" + make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \ + CFLAGS="$(CFLAGS)" "LIBS=" + ipsend: ipf $(OBJS) $(UNIXOBJS) $(CC) $(OBJS) $(UNIXOBJS) -o $@ $(LIBS) $(LLIB) $(ELIB) diff --git a/contrib/ipfilter/ipsend/arp.c b/contrib/ipfilter/ipsend/arp.c index 8e5f7f4b8d42..0e8f556724ac 100644 --- a/contrib/ipfilter/ipsend/arp.c +++ b/contrib/ipfilter/ipsend/arp.c @@ -1,20 +1,21 @@ +/* $NetBSD$ */ + /* * arp.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ -#if defined(__sgi) && (IRIX > 602) -# include +#if !defined(lint) +static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: arp.c,v 2.8 2003/12/01 02:01:15 darrenr Exp"; #endif -#include -#include #include #include -#if !defined(ultrix) && !defined(hpux) +#if !defined(ultrix) && !defined(hpux) && !defined(__hpux) && !defined(__osf__) #include #endif #include -#include +#include #include #include #include @@ -22,23 +23,22 @@ #include #endif #include +#include #include #include +#include +#include +#include #include "ipsend.h" #include "iplang/iplang.h" -#if !defined(lint) -static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: arp.c,v 2.1.4.4 2002/12/06 11:40:35 darrenr Exp $"; -#endif - /* * lookup host and return * its IP address in address * (4 bytes) */ -int resolve(host, address) +int resolve(host, address) char *host, *address; { struct hostent *hp; @@ -90,7 +90,11 @@ char *ether; bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); #ifndef hpux if ((hp = gethostbyaddr(ip, 4, AF_INET))) +# if SOLARIS && (SOLARIS2 >= 10) + if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) +# else if (!(ether_hostton(hp->h_name, ether))) +# endif goto savearp; #endif @@ -122,6 +126,13 @@ char *ether; return -1; } + if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && + (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && + (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { + fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); + return -1; + } + bcopy(ar.arp_ha.sa_data, ether, 6); savearp: bcopy(ether, ethersave, 6); diff --git a/contrib/ipfilter/ipsend/dlcommon.c b/contrib/ipfilter/ipsend/dlcommon.c index 59b283d2b82f..6e351f0fd061 100644 --- a/contrib/ipfilter/ipsend/dlcommon.c +++ b/contrib/ipfilter/ipsend/dlcommon.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Common (shared) DLPI test routines. * Mostly pretty boring boilerplate sorta stuff. @@ -18,7 +20,11 @@ typedef unsigned long ulong; #include #include #include -#include +#ifdef __osf__ +# include +#else +# include +#endif #include #include #include @@ -35,6 +41,7 @@ char *dlstyle(); char *dlmactype(); +void dlinforeq(fd) int fd; { @@ -54,6 +61,7 @@ int fd; syserr("dlinforeq: putmsg"); } +void dlinfoack(fd, bufp) int fd; char *bufp; @@ -82,6 +90,7 @@ char *bufp; err("dlinfoack: short response ctl.len: %d", ctl.len); } +void dlattachreq(fd, ppa) int fd; u_long ppa; @@ -103,6 +112,7 @@ u_long ppa; syserr("dlattachreq: putmsg"); } +void dlenabmultireq(fd, addr, length) int fd; char *addr; @@ -131,6 +141,7 @@ int length; syserr("dlenabmultireq: putmsg"); } +void dldisabmultireq(fd, addr, length) int fd; char *addr; @@ -159,6 +170,7 @@ int length; syserr("dldisabmultireq: putmsg"); } +void dlpromisconreq(fd, level) int fd; u_long level; @@ -181,6 +193,7 @@ u_long level; } +void dlpromiscoff(fd, level) int fd; u_long level; @@ -202,6 +215,7 @@ u_long level; syserr("dlpromiscoff: putmsg"); } +void dlphysaddrreq(fd, addrtype) int fd; u_long addrtype; @@ -223,6 +237,7 @@ u_long addrtype; syserr("dlphysaddrreq: putmsg"); } +void dlsetphysaddrreq(fd, addr, length) int fd; char *addr; @@ -251,6 +266,7 @@ int length; syserr("dlsetphysaddrreq: putmsg"); } +void dldetachreq(fd) int fd; { @@ -270,6 +286,7 @@ int fd; syserr("dldetachreq: putmsg"); } +void dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest) int fd; u_long sap; @@ -299,6 +316,7 @@ u_long xidtest; syserr("dlbindreq: putmsg"); } +void dlunitdatareq(fd, addrp, addrlen, minpri, maxpri, datap, datalen) int fd; u_char *addrp; @@ -333,6 +351,7 @@ int datalen; syserr("dlunitdatareq: putmsg"); } +void dlunbindreq(fd) int fd; { @@ -352,6 +371,7 @@ int fd; syserr("dlunbindreq: putmsg"); } +void dlokack(fd, bufp) int fd; char *bufp; @@ -380,6 +400,7 @@ char *bufp; err("dlokack: short response ctl.len: %d", ctl.len); } +void dlerrorack(fd, bufp) int fd; char *bufp; @@ -408,6 +429,7 @@ char *bufp; err("dlerrorack: short response ctl.len: %d", ctl.len); } +void dlbindack(fd, bufp) int fd; char *bufp; @@ -433,6 +455,7 @@ char *bufp; err("dlbindack: short response ctl.len: %d", ctl.len); } +void dlphysaddrack(fd, bufp) int fd; char *bufp; @@ -695,10 +718,11 @@ union DL_primitives *dlp; printdlerrorack(dlp) union DL_primitives *dlp; { - (void) printf("DL_ERROR_ACK: error_primitive %s errno %s unix_errno %d\n", + (void) printf("DL_ERROR_ACK: error_primitive %s errno %s unix_errno %d: %s\n", dlprim(dlp->error_ack.dl_error_primitive), dlerrno(dlp->error_ack.dl_errno), - dlp->error_ack.dl_unix_errno); + dlp->error_ack.dl_unix_errno, + strerror(dlp->error_ack.dl_unix_errno)); } printdlenabmultireq(dlp) diff --git a/contrib/ipfilter/ipsend/dltest.h b/contrib/ipfilter/ipsend/dltest.h index 4c32c30eb1bc..9fafd9182dc0 100644 --- a/contrib/ipfilter/ipsend/dltest.h +++ b/contrib/ipfilter/ipsend/dltest.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Common DLPI Test Suite header file * diff --git a/contrib/ipfilter/ipsend/hpux.c b/contrib/ipfilter/ipsend/hpux.c index 463fdbfdafff..69f962c77c13 100644 --- a/contrib/ipfilter/ipsend/hpux.c +++ b/contrib/ipfilter/ipsend/hpux.c @@ -1,7 +1,11 @@ +/* $NetBSD$ */ + /* * (C)opyright 1997-1998 Darren Reed. (from tcplog) * - * 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. */ #include #include diff --git a/contrib/ipfilter/ipsend/in_var.h b/contrib/ipfilter/ipsend/in_var.h index b935259019ae..f228bbbb69f2 100644 --- a/contrib/ipfilter/ipsend/in_var.h +++ b/contrib/ipfilter/ipsend/in_var.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* @(#)in_var.h 1.3 88/08/19 SMI; from UCB 7.1 6/5/86 */ /* @@ -173,5 +175,5 @@ struct in_multistep { } struct in_multi *in_addmulti(); -#endif KERNEL +#endif /* KERNEL */ #endif /*!_netinet_in_var_h*/ diff --git a/contrib/ipfilter/ipsend/ip.c b/contrib/ipfilter/ipsend/ip.c index 8d30bf5031ac..8302806f441d 100644 --- a/contrib/ipfilter/ipsend/ip.c +++ b/contrib/ipfilter/ipsend/ip.c @@ -1,25 +1,21 @@ +/* $NetBSD$ */ + /* * ip.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. */ -#if defined(__sgi) && (IRIX > 602) -# include +#if !defined(lint) +static const char sccsid[] = "%W% %G% (C)1995"; +static const char rcsid[] = "@(#)Id: ip.c,v 2.8.2.1 2004/10/19 12:31:48 darrenr Exp"; #endif -#include -#include -#include -#include -#include +#include #include #include #include #include #include #include -#include -#include -#include #include #ifndef linux # include @@ -28,12 +24,13 @@ # include # endif #endif +#include +#include +#include +#include +#include #include "ipsend.h" -#if !defined(lint) -static const char sccsid[] = "%W% %G% (C)1995"; -static const char rcsid[] = "@(#)$Id: ip.c,v 2.1.4.5 2002/12/06 11:40:35 darrenr Exp $"; -#endif static char *ipbuf = NULL, *ethbuf = NULL; @@ -71,7 +68,9 @@ struct in_addr gwip; bcopy((char *)buf, s + sizeof(*eh), len); if (gwip.s_addr == last_gw.s_addr) + { bcopy(last_arp, (char *)A_A eh->ether_dhost, 6); + } else if (arp((char *)&gwip, (char *)A_A eh->ether_dhost) == -1) { perror("arp"); @@ -92,7 +91,8 @@ ip_t *ip; struct in_addr gwip; int frag; { - static struct in_addr last_gw; + static struct in_addr last_gw, local_ip; + static char local_arp[6] = { 0, 0, 0, 0, 0, 0}; static char last_arp[6] = { 0, 0, 0, 0, 0, 0}; static u_short id = 0; ether_header_t *eh; @@ -102,7 +102,7 @@ int frag; if (!ipbuf) { ipbuf = (char *)malloc(65536); - if(!ipbuf) + if (!ipbuf) { perror("malloc failed"); return -2; @@ -113,7 +113,9 @@ int frag; bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost)); if (last_gw.s_addr && (gwip.s_addr == last_gw.s_addr)) + { bcopy(last_arp, (char *)A_A eh->ether_dhost, 6); + } else if (arp((char *)&gwip, (char *)A_A eh->ether_dhost) == -1) { perror("arp"); @@ -127,18 +129,25 @@ int frag; iplen = ip->ip_len; ip->ip_len = htons(iplen); if (!(frag & 2)) { - if (!ip->ip_v) - ip->ip_v = IPVERSION; + if (!IP_V(ip)) + IP_V_A(ip, IPVERSION); if (!ip->ip_id) ip->ip_id = htons(id++); if (!ip->ip_ttl) ip->ip_ttl = 60; } + if (ip->ip_src.s_addr != local_ip.s_addr) { + (void) arp((char *)&ip->ip_src, (char *)A_A local_arp); + bcopy(local_arp, (char *)A_A eh->ether_shost,sizeof(last_arp)); + local_ip = ip->ip_src; + } else + bcopy(local_arp, (char *)A_A eh->ether_shost, 6); + if (!frag || (sizeof(*eh) + iplen < mtu)) { ip->ip_sum = 0; - ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2); + ip->ip_sum = chksum((u_short *)ip, IP_HL(ip) << 2); bcopy((char *)ip, ipbuf + sizeof(*eh), iplen); err = sendip(nfd, ipbuf, sizeof(*eh) + iplen); @@ -155,14 +164,14 @@ int frag; char *s; int i, sent = 0, ts, hlen, olen; - hlen = ip->ip_hl << 2; + hlen = IP_HL(ip) << 2; if (mtu < (hlen + 8)) { fprintf(stderr, "mtu (%d) < ip header size (%d) + 8\n", mtu, hlen); fprintf(stderr, "can't fragment data\n"); return -2; } - ol = (ip->ip_hl << 2) - sizeof(*ip); + ol = (IP_HL(ip) << 2) - sizeof(*ip); for (i = 0, s = (char*)(ip + 1); ol > 0; ) if (*s == IPOPT_EOL) { optcpy[i++] = *s; @@ -223,7 +232,7 @@ int frag; else if (!(ip->ip_off & htons(0x1fff))) { hlen = i + sizeof(*ip); - ip->ip_hl = (sizeof(*ip) + i) >> 2; + IP_HL_A(ip, (sizeof(*ip) + i) >> 2); bcopy(optcpy, (char *)(ip + 1), i); } } @@ -243,45 +252,46 @@ ip_t *ip; struct in_addr gwip; { static tcp_seq iss = 2; - struct tcpiphdr *ti; - tcphdr_t *t; + tcphdr_t *t, *t2; int thlen, i, iplen, hlen; u_32_t lbuf[20]; + ip_t *ip2; iplen = ip->ip_len; - hlen = ip->ip_hl << 2; + hlen = IP_HL(ip) << 2; t = (tcphdr_t *)((char *)ip + hlen); - ti = (struct tcpiphdr *)lbuf; - thlen = t->th_off << 2; + ip2 = (struct ip *)lbuf; + t2 = (tcphdr_t *)((char *)ip2 + hlen); + thlen = TCP_OFF(t) << 2; if (!thlen) thlen = sizeof(tcphdr_t); - bzero((char *)ti, sizeof(*ti)); + bzero((char *)ip2, sizeof(*ip2) + sizeof(*t2)); ip->ip_p = IPPROTO_TCP; - ti->ti_pr = ip->ip_p; - ti->ti_src = ip->ip_src; - ti->ti_dst = ip->ip_dst; - bcopy((char *)ip + hlen, (char *)&ti->ti_sport, thlen); + ip2->ip_p = ip->ip_p; + ip2->ip_src = ip->ip_src; + ip2->ip_dst = ip->ip_dst; + bcopy((char *)ip + hlen, (char *)t2, thlen); - if (!ti->ti_win) - ti->ti_win = htons(4096); + if (!t2->th_win) + t2->th_win = htons(4096); iss += 63; i = sizeof(struct tcpiphdr) / sizeof(long); - if ((ti->ti_flags == TH_SYN) && !ntohs(ip->ip_off) && + if ((t2->th_flags == TH_SYN) && !ntohs(ip->ip_off) && (lbuf[i] != htonl(0x020405b4))) { lbuf[i] = htonl(0x020405b4); bcopy((char *)ip + hlen + thlen, (char *)ip + hlen + thlen + 4, iplen - thlen - hlen); thlen += 4; } - ti->ti_off = thlen >> 2; - ti->ti_len = htons(thlen); + TCP_OFF_A(t2, thlen >> 2); + ip2->ip_len = htons(thlen); ip->ip_len = hlen + thlen; - ti->ti_sum = 0; - ti->ti_sum = chksum((u_short *)ti, thlen + sizeof(ip_t)); + t2->th_sum = 0; + t2->th_sum = chksum((u_short *)ip2, thlen + sizeof(ip_t)); - bcopy((char *)&ti->ti_sport, (char *)ip + hlen, thlen); + bcopy((char *)t2, (char *)ip + hlen, thlen); return send_ip(nfd, mtu, ip, gwip, 1); } @@ -304,16 +314,16 @@ struct in_addr gwip; ti->ti_pr = ip->ip_p; ti->ti_src = ip->ip_src; ti->ti_dst = ip->ip_dst; - bcopy((char *)ip + (ip->ip_hl << 2), + bcopy((char *)ip + (IP_HL(ip) << 2), (char *)&ti->ti_sport, sizeof(udphdr_t)); ti->ti_len = htons(thlen); - ip->ip_len = (ip->ip_hl << 2) + thlen; + ip->ip_len = (IP_HL(ip) << 2) + thlen; ti->ti_sum = 0; ti->ti_sum = chksum((u_short *)ti, thlen + sizeof(ip_t)); bcopy((char *)&ti->ti_sport, - (char *)ip + (ip->ip_hl << 2), sizeof(udphdr_t)); + (char *)ip + (IP_HL(ip) << 2), sizeof(udphdr_t)); return send_ip(nfd, mtu, ip, gwip, 1); } @@ -328,7 +338,7 @@ struct in_addr gwip; { struct icmp *ic; - ic = (struct icmp *)((char *)ip + (ip->ip_hl << 2)); + ic = (struct icmp *)((char *)ip + (IP_HL(ip) << 2)); ic->icmp_cksum = 0; ic->icmp_cksum = chksum((u_short *)ic, sizeof(struct icmp)); diff --git a/contrib/ipfilter/ipsend/ip_var.h b/contrib/ipfilter/ipsend/ip_var.h index ace980079313..b08f4e7a2fd3 100644 --- a/contrib/ipfilter/ipsend/ip_var.h +++ b/contrib/ipfilter/ipsend/ip_var.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* @(#)ip_var.h 1.11 88/08/19 SMI; from UCB 7.1 6/5/86 */ /* @@ -44,7 +46,7 @@ struct ipq { * Note: ipf_next must be at same offset as ipq_next above */ struct ipasfrag { -#if defined(vax) || defined(i386) || defined(__i386__) +#if defined(vax) || defined(i386) u_char ip_hl:4, ip_v:4; #endif diff --git a/contrib/ipfilter/ipsend/ipresend.1 b/contrib/ipfilter/ipsend/ipresend.1 index 6014313587b0..cffc6f3c29b6 100644 --- a/contrib/ipfilter/ipsend/ipresend.1 +++ b/contrib/ipfilter/ipsend/ipresend.1 @@ -1,3 +1,5 @@ +.\" $NetBSD$ +.\" .TH IPRESEND 1 .SH NAME ipresend \- resend IP packets out to network diff --git a/contrib/ipfilter/ipsend/ipresend.c b/contrib/ipfilter/ipsend/ipresend.c index 9252b4b00b18..1db54e19015f 100644 --- a/contrib/ipfilter/ipsend/ipresend.c +++ b/contrib/ipfilter/ipsend/ipresend.c @@ -1,42 +1,33 @@ +/* $NetBSD$ */ + /* * ipresend.c (C) 1995-1998 Darren Reed * - * This was written to test what size TCP fragments would get through - * various TCP/IP packet filters, as used in IP firewalls. In certain - * conditions, enough of the TCP header is missing for unpredictable - * results unless the filter is aware that this can happen. - * * See the IPFILTER.LICENCE file for details on licencing. + * */ -#if defined(__sgi) && (IRIX > 602) -# include +#if !defined(lint) +static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipresend.c,v 2.4 2004/01/08 13:34:31 darrenr Exp"; #endif -#include -#include -#include -#include -#include -#include #include +#include #include #include #include #include #include #include -#include -#include -#include #ifndef linux #include #endif +#include +#include +#include +#include +#include #include "ipsend.h" -#if !defined(lint) -static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.1.4.4 2002/12/06 11:40:35 darrenr Exp $"; -#endif - extern char *optarg; extern int optind; diff --git a/contrib/ipfilter/ipsend/ipsend.1 b/contrib/ipfilter/ipsend/ipsend.1 index f2f806658dd3..33320f3bd57b 100644 --- a/contrib/ipfilter/ipsend/ipsend.1 +++ b/contrib/ipfilter/ipsend/ipsend.1 @@ -1,3 +1,5 @@ +.\" $NetBSD$ +.\" .TH IPSEND 1 .SH NAME ipsend \- sends IP packets diff --git a/contrib/ipfilter/ipsend/ipsend.h b/contrib/ipfilter/ipsend/ipsend.h index 71e5490c6ece..be98c1b90d42 100644 --- a/contrib/ipfilter/ipsend/ipsend.h +++ b/contrib/ipfilter/ipsend/ipsend.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * ipsend.h (C) 1997-1998 Darren Reed * @@ -6,7 +8,11 @@ * conditions, enough of the TCP header is missing for unpredictable * results unless the filter is aware that this can happen. * - * See the IPFILTER.LICENCE file for details on licencing. + * The author provides this program as-is, with no gaurantee for its + * suitability for any specific purpose. The author takes no responsibility + * for the misuse/abuse of this program and provides it for the sole purpose + * of testing packet filter policies. This file maybe distributed freely + * providing it is not modified and that this notice remains in tact. * */ #ifndef __P @@ -17,13 +23,14 @@ # endif #endif -#include "ip_compat.h" +#include + +#include "ipf.h" #ifdef linux #include #endif #include "tcpip.h" #include "ipt.h" -#include "ipf.h" extern int resolve __P((char *, char *)); extern int arp __P((char *, char *)); @@ -35,10 +42,10 @@ extern int send_udp __P((int, int, ip_t *, struct in_addr)); extern int send_icmp __P((int, int, ip_t *, struct in_addr)); extern int send_packet __P((int, int, ip_t *, struct in_addr)); extern int send_packets __P((char *, int, ip_t *, struct in_addr)); -extern u_short seclevel __P((char *)); +extern u_short ipseclevel __P((char *)); extern u_32_t buildopts __P((char *, char *, int)); extern int addipopt __P((char *, struct ipopt_names *, int, char *)); -extern int initdevice __P((char *, int, int)); +extern int initdevice __P((char *, int)); extern int sendip __P((int, char *, int)); #ifdef linux extern struct sock *find_tcp __P((int, struct tcpiphdr *)); @@ -55,7 +62,6 @@ extern void ip_test5 __P((char *, int, ip_t *, struct in_addr, int)); extern void ip_test6 __P((char *, int, ip_t *, struct in_addr, int)); extern void ip_test7 __P((char *, int, ip_t *, struct in_addr, int)); extern int do_socket __P((char *, int, struct tcpiphdr *, struct in_addr)); -extern int openkmem __P((void)); extern int kmemcpy __P((char *, void *, int)); #define KMCPY(a,b,c) kmemcpy((char *)(a), (void *)(b), (int)(c)) @@ -63,9 +69,3 @@ extern int kmemcpy __P((char *, void *, int)); #ifndef OPT_RAW #define OPT_RAW 0x80000 #endif - -#ifndef __STDC__ -# ifndef const -# define const -# endif -#endif diff --git a/contrib/ipfilter/ipsend/ipsopt.c b/contrib/ipfilter/ipsend/ipsopt.c index 144c86f0e9d8..7f1670568f35 100644 --- a/contrib/ipfilter/ipsend/ipsopt.c +++ b/contrib/ipfilter/ipsend/ipsopt.c @@ -1,21 +1,25 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1995-1998 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. + * */ -#if defined(__sgi) && (IRIX > 602) -# include +#if !defined(lint) +static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipsopt.c,v 2.4.4.1 2004/03/23 12:58:05 darrenr Exp"; #endif #include -#include -#include -#include #include #include #include #include #include #include +#include +#include +#include #ifndef linux #include #endif @@ -23,9 +27,13 @@ #include #include "ipsend.h" -#if !defined(lint) -static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.1.4.5 2004/04/10 11:50:52 darrenr Exp $"; + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif #endif @@ -53,7 +61,7 @@ struct ipopt_names secnames[] = { }; -u_short seclevel(slevel) +u_short ipseclevel(slevel) char *slevel; { struct ipopt_names *so; @@ -108,7 +116,7 @@ char *class; switch (io->on_value) { case IPOPT_SECURITY : - lvl = seclevel(class); + lvl = ipseclevel(class); *(op - 1) = lvl; break; case IPOPT_LSRR : diff --git a/contrib/ipfilter/ipsend/iptest.c b/contrib/ipfilter/ipsend/iptest.c index 72d0d7825640..45f8f3a65f50 100644 --- a/contrib/ipfilter/ipsend/iptest.c +++ b/contrib/ipfilter/ipsend/iptest.c @@ -1,21 +1,15 @@ +/* $NetBSD$ */ + /* * ipsend.c (C) 1995-1998 Darren Reed * - * This was written to test what size TCP fragments would get through - * various TCP/IP packet filters, as used in IP firewalls. In certain - * conditions, enough of the TCP header is missing for unpredictable - * results unless the filter is aware that this can happen. - * * See the IPFILTER.LICENCE file for details on licencing. + * */ -#if defined(__sgi) && (IRIX > 602) -# include +#if !defined(lint) +static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: iptest.c,v 2.6 2004/01/08 13:34:31 darrenr Exp"; #endif -#include -#include -#include -#include -#include #include #include #include @@ -24,22 +18,19 @@ #include #include #include -#include -#include -#include #ifndef linux #include #endif #ifdef linux #include #endif +#include +#include +#include +#include +#include #include "ipsend.h" -#if !defined(lint) -static const char sccsid[] = "%W% %G% (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: iptest.c,v 2.2.2.4 2002/12/06 11:40:35 darrenr Exp $"; -#endif - extern char *optarg; extern int optind; @@ -111,7 +102,7 @@ char **argv; ip = (ip_t *)calloc(1, 65536); ti = (struct tcpiphdr *)ip; ip->ip_len = sizeof(*ip); - ip->ip_hl = sizeof(*ip) >> 2; + IP_HL_A(ip, sizeof(*ip) >> 2); while ((c = getopt(argc, argv, "1234567d:g:m:p:s:")) != -1) switch (c) diff --git a/contrib/ipfilter/ipsend/larp.c b/contrib/ipfilter/ipsend/larp.c index d178d644895c..a8e782e6bf7b 100644 --- a/contrib/ipfilter/ipsend/larp.c +++ b/contrib/ipfilter/ipsend/larp.c @@ -1,21 +1,25 @@ +/* $NetBSD$ */ + /* * larp.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. + * */ #if !defined(lint) static const char sccsid[] = "@(#)larp.c 1.1 8/19/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: larp.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $"; +static const char rcsid[] = "@(#)Id: larp.c,v 2.4 2003/12/01 02:01:16 darrenr Exp"; #endif -#include -#include +#include #include #include #include -#include #include #include #include +#include +#include +#include #include "ip_compat.h" #include "iplang/iplang.h" @@ -25,7 +29,7 @@ static const char rcsid[] = "@(#)$Id: larp.c,v 2.1.4.1 2001/06/26 10:43:22 darre * its IP address in address * (4 bytes) */ -int resolve(host, address) +int resolve(host, address) char *host, *address; { struct hostent *hp; diff --git a/contrib/ipfilter/ipsend/linux.h b/contrib/ipfilter/ipsend/linux.h index 2d2a243c4d96..d8296bafae8a 100644 --- a/contrib/ipfilter/ipsend/linux.h +++ b/contrib/ipfilter/ipsend/linux.h @@ -1,7 +1,11 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1995-1998 by Darren Reed. * - * See the IPFILTER.LICENCE file for details on licencing. + * This code may be freely distributed as long as it retains this notice + * and is not changed in any way. The author accepts no responsibility + * for the use of this software. I hate legaleese, don't you ? * * @(#)linux.h 1.1 8/19/95 */ diff --git a/contrib/ipfilter/ipsend/lsock.c b/contrib/ipfilter/ipsend/lsock.c index 23a762114f81..abe664e5cb95 100644 --- a/contrib/ipfilter/ipsend/lsock.c +++ b/contrib/ipfilter/ipsend/lsock.c @@ -1,14 +1,14 @@ +/* $NetBSD$ */ + /* * lsock.c (C) 1995-1998 Darren Reed * * See the IPFILTER.LICENCE file for details on licencing. + * */ #if !defined(lint) static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: lsock.c,v 2.1.4.3 2002/12/06 11:40:36 darrenr Exp $"; -#endif -#if defined(__sgi) && (IRIX > 602) -# include +static const char rcsid[] = "@(#)Id: lsock.c,v 2.3 2001/06/09 17:09:26 darrenr Exp"; #endif #include #include @@ -226,7 +226,7 @@ struct in_addr gwip; (void) getsockname(fd, (struct sockaddr *)&lsin, &len); ti->ti_sport = lsin.sin_port; printf("sport %d\n", ntohs(lsin.sin_port)); - nfd = initdevice(dev, ntohs(lsin.sin_port), 0); + nfd = initdevice(dev, 0); if (!(s = find_tcp(fd, ti))) return -1; diff --git a/contrib/ipfilter/ipsend/resend.c b/contrib/ipfilter/ipsend/resend.c index 646da1a22e05..07220dfb7745 100644 --- a/contrib/ipfilter/ipsend/resend.c +++ b/contrib/ipfilter/ipsend/resend.c @@ -1,21 +1,16 @@ +/* $NetBSD$ */ + /* * resend.c (C) 1995-1998 Darren Reed * - * This was written to test what size TCP fragments would get through - * various TCP/IP packet filters, as used in IP firewalls. In certain - * conditions, enough of the TCP header is missing for unpredictable - * results unless the filter is aware that this can happen. - * * See the IPFILTER.LICENCE file for details on licencing. + * */ -#if defined(__sgi) && (IRIX > 602) -# include +#if !defined(lint) +static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: resend.c,v 2.8 2004/01/08 13:34:31 darrenr Exp"; #endif -#include -#include -#include -#include -#include +#include #include #include #include @@ -24,9 +19,6 @@ #include #include #include -#include -#include -#include #ifndef linux # include # include @@ -34,14 +26,13 @@ # include # endif #endif +#include +#include +#include +#include +#include #include "ipsend.h" -#if !defined(lint) -static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: resend.c,v 2.1.4.5 2002/12/06 11:40:36 darrenr Exp $"; -#endif - - extern int opts; static u_char pbuf[65536]; /* 1 big packet */ @@ -54,7 +45,7 @@ ip_t *ip; tcphdr_t *t; int i, j; - t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2)); + t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); if (ip->ip_tos) printf("tos %#x ", ip->ip_tos); if (ip->ip_off & 0x3fff) @@ -88,13 +79,13 @@ char *datain; ether_header_t *eh; char dhost[6]; ip_t *ip; - int fd, wfd = initdevice(dev, 0, 5), len, i; + int fd, wfd = initdevice(dev, 5), len, i; if (datain) fd = (*r->r_open)(datain); else fd = (*r->r_open)("-"); - + if (fd < 0) exit(-1); @@ -130,7 +121,7 @@ char *datain; sizeof(dhost)); if (!ip->ip_sum) ip->ip_sum = chksum((u_short *)ip, - ip->ip_hl << 2); + IP_HL(ip) << 2); bcopy(ip, (char *)(eh + 1), len); len += sizeof(*eh); printpacket(ip); diff --git a/contrib/ipfilter/ipsend/sdlpi.c b/contrib/ipfilter/ipsend/sdlpi.c index dcd842211e03..215223abb241 100644 --- a/contrib/ipfilter/ipsend/sdlpi.c +++ b/contrib/ipfilter/ipsend/sdlpi.c @@ -1,7 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. + * */ #include @@ -19,10 +22,17 @@ #include #ifdef sun -#include -#include +# include +# include +#endif +#ifdef __osf__ +# include +#else +# include +#endif +#ifdef __hpux +# include #endif -#include #include #include @@ -38,7 +48,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)sdlpi.c 1.3 10/30/95 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: sdlpi.c,v 2.1.4.2 2001/06/26 10:43:22 darrenr Exp $"; +static const char rcsid[] = "@(#)Id: sdlpi.c,v 2.8.2.1 2004/12/09 19:41:13 darrenr Exp"; #endif #define CHUNKSIZE 8192 @@ -49,9 +59,9 @@ static const char rcsid[] = "@(#)$Id: sdlpi.c,v 2.1.4.2 2001/06/26 10:43:22 darr * Be careful to only include those defined in the flags option for the * interface are included in the header size. */ -int initdevice(device, sport, tout) +int initdevice(device, tout) char *device; -int sport, tout; +int tout; { char devname[16], *s, buf[256]; int i, fd; @@ -60,7 +70,7 @@ int sport, tout; (void) strncat(devname, device, sizeof(devname) - strlen(devname)); s = devname + 5; - while (*s && !isdigit(*s)) + while (*s && !ISDIGIT(*s)) s++; if (!*s) { @@ -79,24 +89,43 @@ int sport, tout; exit(-1); } - if (dlattachreq(fd, i) == -1 || dlokack(fd, buf) == -1) + if (dlattachreq(fd, i) == -1) { - fprintf(stderr, "DLPI error\n"); + fprintf(stderr, "dlattachreq: DLPI error\n"); exit(-1); } + else if (dlokack(fd, buf) == -1) + { + fprintf(stderr, "dlokack(attach): DLPI error\n"); + exit(-1); + } +#ifdef DL_HP_RAWDLS + if (dlpromisconreq(fd, DL_PROMISC_SAP) < 0) + { + fprintf(stderr, "dlpromisconreq: DL_PROMISC_PHYS error\n"); + exit(-1); + } + else if (dlokack(fd, buf) < 0) + { + fprintf(stderr, "dlokack(promisc): DLPI error\n"); + exit(-1); + } + /* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */ + + dlbindreq(fd, 22, 1, DL_HP_RAWDLS, 0, 0); +#else dlbindreq(fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0); +#endif dlbindack(fd, buf); /* * write full headers */ -#ifdef sun /* we require RAW DLPI mode, which is a Sun extension */ +#ifdef DLIOCRAW /* we require RAW DLPI mode, which is a Sun extension */ if (strioctl(fd, DLIOCRAW, -1, 0, NULL) == -1) { fprintf(stderr, "DLIOCRAW error\n"); exit(-1); } -#else -you lose #endif return fd; } @@ -109,8 +138,19 @@ int sendip(fd, pkt, len) int fd, len; char *pkt; { - struct strbuf dbuf, *dp = &dbuf; + struct strbuf dbuf, *dp = &dbuf, *cp = NULL; + int pri = 0; +#ifdef DL_HP_RAWDLS + struct strbuf cbuf; + dl_hp_rawdata_req_t raw; + cp = &cbuf; + raw.dl_primitive = DL_HP_RAWDATA_REQ; + cp->len = sizeof(raw); + cp->buf = (char *)&raw; + cp->maxlen = cp->len; + pri = MSG_HIPRI; +#endif /* * construct NIT STREAMS messages, first control then data. */ @@ -118,7 +158,7 @@ char *pkt; dp->len = len; dp->maxlen = dp->len; - if (putmsg(fd, NULL, dp, 0) == -1) + if (putmsg(fd, cp, dp, pri) == -1) { perror("putmsg"); return -1; @@ -130,3 +170,4 @@ char *pkt; } return len; } + diff --git a/contrib/ipfilter/ipsend/sirix.c b/contrib/ipfilter/ipsend/sirix.c index 8f491f7866bf..39a09925b491 100644 --- a/contrib/ipfilter/ipsend/sirix.c +++ b/contrib/ipfilter/ipsend/sirix.c @@ -1,12 +1,12 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. * (C)opyright 1997 Marc Boucher. * * See the IPFILTER.LICENCE file for details on licencing. + * */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif #include #include #include @@ -23,17 +23,15 @@ #include #include #include -#include -#include -#include #include "ipsend.h" +#include #if !defined(lint) && defined(LIBC_SCCS) static char sirix[] = "@(#)sirix.c 1.0 10/9/97 (C)1997 Marc Boucher"; #endif -int initdevice(char *device, int sport, int tout) +int initdevice(char *device, int tout) { int fd; struct sockaddr_raw sr; diff --git a/contrib/ipfilter/ipsend/slinux.c b/contrib/ipfilter/ipsend/slinux.c index 7438d1c25cf9..3bc7f09c4db7 100644 --- a/contrib/ipfilter/ipsend/slinux.c +++ b/contrib/ipfilter/ipsend/slinux.c @@ -1,7 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. + * */ #include @@ -27,7 +30,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)slinux.c 1.2 8/25/95"; -static const char rcsid[] = "@(#)$Id: slinux.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $"; +static const char rcsid[] = "@(#)Id: slinux.c,v 2.3 2001/06/09 17:09:26 darrenr Exp"; #endif #define CHUNKSIZE 8192 @@ -42,9 +45,9 @@ static int timeout; static char *eth_dev = NULL; -int initdevice(dev, sport, spare) +int initdevice(dev, spare) char *dev; -int sport, spare; +int spare; { int fd; diff --git a/contrib/ipfilter/ipsend/snit.c b/contrib/ipfilter/ipsend/snit.c index 6f2c66269e2a..a4b19b9b83ee 100644 --- a/contrib/ipfilter/ipsend/snit.c +++ b/contrib/ipfilter/ipsend/snit.c @@ -1,7 +1,10 @@ +/* $NetBSD$ */ + /* * (C)opyright 1992-1998 Darren Reed. (from tcplog) * * See the IPFILTER.LICENCE file for details on licencing. + * */ #include @@ -38,7 +41,7 @@ #if !defined(lint) static const char sccsid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: snit.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $"; +static const char rcsid[] = "@(#)Id: snit.c,v 2.3 2001/06/09 17:09:26 darrenr Exp"; #endif #define CHUNKSIZE 8192 @@ -54,9 +57,9 @@ static const char rcsid[] = "@(#)$Id: snit.c,v 2.1.4.1 2001/06/26 10:43:22 darre static int timeout; -int initdevice(device, sport, tout) +int initdevice(device, tout) char *device; -int sport, tout; +int tout; { struct strioctl si; struct timeval to; diff --git a/contrib/ipfilter/ipsend/sockraw.c b/contrib/ipfilter/ipsend/sockraw.c new file mode 100644 index 000000000000..822c146f8cf3 --- /dev/null +++ b/contrib/ipfilter/ipsend/sockraw.c @@ -0,0 +1,89 @@ +/* $NetBSD$ */ + +/* + * (C)opyright 2000 Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * WARNING: Attempting to use this .c file on HP-UX 11.00 will cause the + * system to crash. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipsend.h" + +#if !defined(lint) && defined(LIBC_SCCS) +static char sirix[] = "@(#)sirix.c 1.0 10/9/97 (C)1997 Marc Boucher"; +#endif + + +int initdevice(char *device, int tout) +{ + struct sockaddr s; + struct ifreq ifr; + int fd; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name); + + if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) + { + perror("socket(AF_INET, SOCK_RAW, IPPROTO_RAW)"); + return -1; + } + + if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) + { + perror("ioctl SIOCGIFADDR"); + return -1; + } + + bzero((char *)&s, sizeof(s)); + s.sa_family = AF_INET; + bcopy(&ifr.ifr_addr, s.sa_data, 4); + if (bind(fd, &s, sizeof(s)) == -1) + perror("bind"); + return fd; +} + + +/* + * output an IP packet + */ +int sendip(int fd, char *pkt, int len) +{ + struct ether_header *eh; + struct sockaddr_in sin; + + eh = (struct ether_header *)pkt; + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + pkt += 14; + len -= 14; + bcopy(pkt + 12, (char *)&sin.sin_addr, 4); + + if (sendto(fd, pkt, len, 0, &sin, sizeof(sin)) == -1) + { + perror("send"); + return -1; + } + + return len; +} diff --git a/contrib/ipfilter/ipsend/tcpip.h b/contrib/ipfilter/ipsend/tcpip.h index c7355934017b..0d3e04031ff0 100644 --- a/contrib/ipfilter/ipsend/tcpip.h +++ b/contrib/ipfilter/ipsend/tcpip.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. @@ -10,11 +12,7 @@ * 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. * @@ -31,7 +29,7 @@ * SUCH DAMAGE. * * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 - * $Id: tcpip.h,v 2.1 1999/08/04 17:31:16 darrenr Exp $ + * Id: tcpip.h,v 2.2.2.3 2004/05/26 15:45:48 darrenr Exp */ #ifndef _NETINET_TCPIP_H_ @@ -54,12 +52,9 @@ struct ipovly { */ struct tcpiphdr { struct ipovly ti_i; /* overlaid ip structure */ -#ifdef linux - tcphdr_t ti_t; -#else struct tcphdr ti_t; /* tcp header */ -#endif }; + #ifdef notyet /* * Tcp+ip header, after ip options removed but including TCP options. diff --git a/contrib/ipfilter/ipt.h b/contrib/ipfilter/ipt.h index 677c74aff7e3..6a14fe5a57d2 100644 --- a/contrib/ipfilter/ipt.h +++ b/contrib/ipfilter/ipt.h @@ -1,8 +1,11 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. - * $Id: ipt.h,v 2.2.2.1 2001/06/26 10:43:19 darrenr Exp $ + * + * Id: ipt.h,v 2.6 2003/02/16 02:33:09 darrenr Exp */ #ifndef __IPT_H__ @@ -24,8 +27,11 @@ struct ipread { int (*r_open) __P((char *)); int (*r_close) __P((void)); int (*r_readip) __P((char *, int, char **, int *)); + int r_flags; }; +#define R_DO_CKSUM 0x01 + extern void debug __P((char *, ...)); extern void verbose __P((char *, ...)); diff --git a/contrib/ipfilter/kmem.h b/contrib/ipfilter/kmem.h index f7056c2cf867..7cb66357fc0d 100644 --- a/contrib/ipfilter/kmem.h +++ b/contrib/ipfilter/kmem.h @@ -1,8 +1,10 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1993-2001 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. - * $Id: kmem.h,v 2.2.2.4 2002/01/01 13:43:48 darrenr Exp $ + * Id: kmem.h,v 2.5 2002/08/21 22:57:36 darrenr Exp */ #ifndef __KMEM_H__ @@ -18,7 +20,6 @@ extern int openkmem __P((char *, char *)); extern int kmemcpy __P((char *, long, int)); extern int kstrncpy __P((char *, long, int)); -extern char *getifname __P((void *)); #if defined(__NetBSD__) || defined(__OpenBSD) # include diff --git a/contrib/ipfilter/l4check/http.ok b/contrib/ipfilter/l4check/http.ok index 2b5d2c15266d..0e7dd90187e0 100644 --- a/contrib/ipfilter/l4check/http.ok +++ b/contrib/ipfilter/l4check/http.ok @@ -1 +1 @@ - \ No newline at end of file + diff --git a/contrib/ipfilter/l4check/l4check.c b/contrib/ipfilter/l4check/l4check.c index 23ac79af849b..68c41de4e5a3 100644 --- a/contrib/ipfilter/l4check/l4check.c +++ b/contrib/ipfilter/l4check/l4check.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * (C)Copyright March, 2000 - Darren Reed. */ @@ -141,8 +143,7 @@ void closel4(l4, dead) l4cfg_t *l4; int dead; { - if (l4->l4_fd != -1) - close(l4->l4_fd); + close(l4->l4_fd); l4->l4_fd = -1; l4->l4_rw = -1; if (dead && l4->l4_alive) { @@ -308,7 +309,7 @@ int runconfig() if (opts & OPT_VERBOSE) fprintf(stderr, "failed\n"); perror("connect"); - closel4(l4, 1); + close(fd); fd = -1; } else { if (opts & OPT_VERBOSE) @@ -417,10 +418,10 @@ u_short *portp; *port++ = '\0'; #ifdef HAVE_INET_ATON - if (isdigit(*host) && inet_aton(host, &ip)) + if (ISDIGIT(*host) && inet_aton(host, &ip)) *ipp = ip.s_addr; #else - if (isdigit(*host)) + if (ISDIGIT(*host)) *ipp = inet_addr(host); #endif else { @@ -433,7 +434,7 @@ u_short *portp; } if (port) { - if (isdigit(*port)) + if (ISDIGIT(*port)) *portp = htons(atoi(port)); else { sp = getservbyname(port, "tcp"); @@ -526,7 +527,7 @@ char *filename; /* * Skip leading whitespace */ - for (line = buf; (c = *line) && isspace(c); line++) + for (line = buf; (c = *line) && ISSPACE(c); line++) ; if (!*line) continue; @@ -606,14 +607,14 @@ char *filename; } bcopy((char *)&template, (char *)l4, sizeof(*l4)); l4->l4_sin.sin_addr = ipn->in_in[0]; - l4->l4_sin.sin_port = ipn->in_pnext; + l4->l4_sin.sin_port = ipn->in_pnext; l4->l4_next = l4list; l4list = l4; } else if (!strcasecmp(t, "connect")) { s = strtok(NULL, " \t"); if (s) t = strtok(NULL, "\t"); - if (!s || !t) { + if (!s || !t) { errtxt = line; err = -1; break; @@ -635,7 +636,7 @@ char *filename; } } else if (!strcasecmp(t, "probe")) { s = strtok(NULL, " \t"); - if (!s) { + if (!s) { errtxt = line; err = -1; break; @@ -683,13 +684,13 @@ char *filename; } } else if (!strcasecmp(t, "response")) { s = strtok(NULL, " \t"); - if (!s) { + if (!s) { errtxt = line; err = -1; break; } else if (!strcasecmp(s, "timeout")) { t = strtok(NULL, " \t"); - if (!t) { + if (!t) { errtxt = line; err = -1; break; diff --git a/contrib/ipfilter/lib/Makefile b/contrib/ipfilter/lib/Makefile new file mode 100644 index 000000000000..d448ba0f4c1c --- /dev/null +++ b/contrib/ipfilter/lib/Makefile @@ -0,0 +1,309 @@ +INCDEP=$(TOP)/ip_compat.h $(TOP)/ip_fil.h $(TOP)/ipf.h + +LIBOBJS=$(DEST)/addicmp.o \ + $(DEST)/addipopt.o \ + $(DEST)/addkeep.o \ + $(DEST)/bcopywrap.o \ + $(DEST)/binprint.o \ + $(DEST)/buildopts.o \ + $(DEST)/checkrev.o \ + $(DEST)/count6bits.o \ + $(DEST)/count4bits.o \ + $(DEST)/debug.o \ + $(DEST)/extras.o \ + $(DEST)/facpri.o \ + $(DEST)/flags.o \ + $(DEST)/fill6bits.o \ + $(DEST)/genmask.o \ + $(DEST)/gethost.o \ + $(DEST)/getifname.o \ + $(DEST)/getline.o \ + $(DEST)/getnattype.o \ + $(DEST)/getport.o \ + $(DEST)/getportproto.o \ + $(DEST)/getproto.o \ + $(DEST)/getsumd.o \ + $(DEST)/hexdump.o \ + $(DEST)/hostmask.o \ + $(DEST)/hostname.o \ + $(DEST)/hostnum.o \ + $(DEST)/icmpcode.o \ + $(DEST)/inet_addr.o \ + $(DEST)/initparse.o \ + $(DEST)/ionames.o \ + $(DEST)/ipoptsec.o \ + $(DEST)/ipf_dotuning.o \ + $(DEST)/ipft_ef.o \ + $(DEST)/ipft_hx.o \ + $(DEST)/ipft_pc.o \ + $(DEST)/ipft_sn.o \ + $(DEST)/ipft_td.o \ + $(DEST)/ipft_tx.o \ + $(DEST)/kmem.o \ + $(DEST)/kmemcpywrap.o \ + $(DEST)/kvatoname.o \ + $(DEST)/load_hash.o \ + $(DEST)/load_hashnode.o \ + $(DEST)/load_pool.o \ + $(DEST)/load_poolnode.o \ + $(DEST)/loglevel.o \ + $(DEST)/make_range.o \ + $(DEST)/mutex_emul.o \ + $(DEST)/nametokva.o \ + $(DEST)/nat_setgroupmap.o \ + $(DEST)/ntomask.o \ + $(DEST)/optname.o \ + $(DEST)/optprint.o \ + $(DEST)/optprintv6.o \ + $(DEST)/optvalue.o \ + $(DEST)/portname.o \ + $(DEST)/portnum.o \ + $(DEST)/ports.o \ + $(DEST)/print_toif.o \ + $(DEST)/printactivenat.o \ + $(DEST)/printaps.o \ + $(DEST)/printbuf.o \ + $(DEST)/printhash.o \ + $(DEST)/printhashnode.o \ + $(DEST)/printip.o \ + $(DEST)/printpool.o \ + $(DEST)/printpoolnode.o \ + $(DEST)/printfr.o \ + $(DEST)/printfraginfo.o \ + $(DEST)/printhostmap.o \ + $(DEST)/printifname.o \ + $(DEST)/printhostmask.o \ + $(DEST)/printlog.o \ + $(DEST)/printmask.o \ + $(DEST)/printnat.o \ + $(DEST)/printportcmp.o \ + $(DEST)/printpacket.o \ + $(DEST)/printpacket6.o \ + $(DEST)/printsbuf.o \ + $(DEST)/printstate.o \ + $(DEST)/printtunable.o \ + $(DEST)/ratoi.o \ + $(DEST)/ratoui.o \ + $(DEST)/remove_hash.o \ + $(DEST)/remove_hashnode.o \ + $(DEST)/remove_pool.o \ + $(DEST)/remove_poolnode.o \ + $(DEST)/resetlexer.o \ + $(DEST)/rwlock_emul.o \ + $(DEST)/tcpflags.o \ + $(DEST)/tcp_flags.o \ + $(DEST)/to_interface.o \ + $(DEST)/var.o \ + $(DEST)/verbose.o \ + $(DEST)/v6ionames.o \ + $(DEST)/v6optvalue.o + +$(DEST)/libipf.a: $(LIBOBJS) + /bin/rm -f $@ + ar $(AROPTS) $@ $(LIBOBJS) + $(RANLIB) $@ + +$(DEST)/addicmp.o: $(LIBSRC)/addicmp.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/addicmp.c -o $@ +$(DEST)/addipopt.o: $(LIBSRC)/addipopt.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/addipopt.c -o $@ +$(DEST)/addkeep.o: $(LIBSRC)/addkeep.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/addkeep.c -o $@ +$(DEST)/bcopywrap.o: $(LIBSRC)/bcopywrap.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/bcopywrap.c -o $@ +$(DEST)/binprint.o: $(LIBSRC)/binprint.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/binprint.c -o $@ +$(DEST)/buildopts.o: $(LIBSRC)/buildopts.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/buildopts.c -o $@ +$(DEST)/count6bits.o: $(LIBSRC)/count6bits.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/count6bits.c -o $@ +$(DEST)/checkrev.o: $(LIBSRC)/checkrev.c $(INCDEP) $(TOP)/ipl.h + $(CC) $(CCARGS) -c $(LIBSRC)/checkrev.c -o $@ +$(DEST)/count4bits.o: $(LIBSRC)/count4bits.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/count4bits.c -o $@ +$(DEST)/debug.o: $(LIBSRC)/debug.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/debug.c -o $@ +$(DEST)/extras.o: $(LIBSRC)/extras.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/extras.c -o $@ +$(DEST)/facpri.o: $(LIBSRC)/facpri.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/facpri.c -o $@ +$(DEST)/fill6bits.o: $(LIBSRC)/fill6bits.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/fill6bits.c -o $@ +$(DEST)/flags.o: $(LIBSRC)/flags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/flags.c -o $@ +$(DEST)/genmask.o: $(LIBSRC)/genmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/genmask.c -o $@ +$(DEST)/getline.o: $(LIBSRC)/getline.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getline.c -o $@ +$(DEST)/gethost.o: $(LIBSRC)/gethost.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/gethost.c -o $@ +$(DEST)/getifname.o: $(LIBSRC)/getifname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getifname.c -o $@ +$(DEST)/getnattype.o: $(LIBSRC)/getnattype.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getnattype.c -o $@ +$(DEST)/getport.o: $(LIBSRC)/getport.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getport.c -o $@ +$(DEST)/getportproto.o: $(LIBSRC)/getportproto.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getportproto.c -o $@ +$(DEST)/getproto.o: $(LIBSRC)/getproto.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getproto.c -o $@ +$(DEST)/getsumd.o: $(LIBSRC)/getsumd.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/getsumd.c -o $@ +$(DEST)/hexdump.o: $(LIBSRC)/hexdump.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hexdump.c -o $@ +$(DEST)/hostmask.o: $(LIBSRC)/hostmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hostmask.c -o $@ +$(DEST)/hostname.o: $(LIBSRC)/hostname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hostname.c -o $@ +$(DEST)/hostnum.o: $(LIBSRC)/hostnum.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/hostnum.c -o $@ +$(DEST)/icmpcode.o: $(LIBSRC)/icmpcode.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/icmpcode.c -o $@ +$(DEST)/ipoptsec.o: $(LIBSRC)/ipoptsec.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipoptsec.c -o $@ +$(DEST)/inet_addr.o: $(LIBSRC)/inet_addr.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/inet_addr.c -o $@ +$(DEST)/initparse.o: $(LIBSRC)/initparse.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/initparse.c -o $@ +$(DEST)/ionames.o: $(LIBSRC)/ionames.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ionames.c -o $@ +$(DEST)/ipf_dotuning.o: $(LIBSRC)/ipf_dotuning.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipf_dotuning.c -o $@ +$(DEST)/ipft_ef.o: $(LIBSRC)/ipft_ef.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_ef.c -o $@ +$(DEST)/ipft_hx.o: $(LIBSRC)/ipft_hx.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_hx.c -o $@ +$(DEST)/ipft_pc.o: $(LIBSRC)/ipft_pc.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_pc.c -o $@ +$(DEST)/ipft_sn.o: $(LIBSRC)/ipft_sn.c $(TOP)/snoop.h + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_sn.c -o $@ +$(DEST)/ipft_td.o: $(LIBSRC)/ipft_td.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_td.c -o $@ +$(DEST)/ipft_tx.o: $(LIBSRC)/ipft_tx.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ipft_tx.c -o $@ +$(DEST)/kmem.o: $(LIBSRC)/kmem.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/kmem.c -o $@ +$(DEST)/kmemcpywrap.o: $(LIBSRC)/kmemcpywrap.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/kmemcpywrap.c -o $@ +$(DEST)/kvatoname.o: $(LIBSRC)/kvatoname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/kvatoname.c -o $@ +$(DEST)/load_hash.o: $(LIBSRC)/load_hash.c $(INCDEP) $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_hash.c -o $@ +$(DEST)/load_hashnode.o: $(LIBSRC)/load_hashnode.c $(INCDEP) $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_hashnode.c -o $@ +$(DEST)/load_pool.o: $(LIBSRC)/load_pool.c $(INCDEP) $(TOP)/ip_pool.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_pool.c -o $@ +$(DEST)/load_poolnode.o: $(LIBSRC)/load_poolnode.c $(INCDEP) $(TOP)/ip_pool.h + $(CC) $(CCARGS) -c $(LIBSRC)/load_poolnode.c -o $@ +$(DEST)/make_range.o: $(LIBSRC)/make_range.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/make_range.c -o $@ +$(DEST)/mutex_emul.o: $(LIBSRC)/mutex_emul.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/mutex_emul.c -o $@ +$(DEST)/nametokva.o: $(LIBSRC)/nametokva.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/nametokva.c -o $@ +$(DEST)/nat_setgroupmap.o: $(LIBSRC)/nat_setgroupmap.c $(TOP)/ip_compat.h \ + $(TOP)/ipf.h $(TOP)/ip_nat.h + $(CC) $(CCARGS) -c $(LIBSRC)/nat_setgroupmap.c -o $@ +$(DEST)/ntomask.o: $(LIBSRC)/ntomask.c $(TOP)/ip_compat.h + $(CC) $(CCARGS) -c $(LIBSRC)/ntomask.c -o $@ +$(DEST)/loglevel.o: $(LIBSRC)/loglevel.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/loglevel.c -o $@ +$(DEST)/optname.o: $(LIBSRC)/optname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optname.c -o $@ +$(DEST)/optprint.o: $(LIBSRC)/optprint.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optprint.c -o $@ +$(DEST)/optprintv6.o: $(LIBSRC)/optprintv6.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optprintv6.c -o $@ +$(DEST)/optvalue.o: $(LIBSRC)/optvalue.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/optvalue.c -o $@ +$(DEST)/portname.o: $(LIBSRC)/portname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/portname.c -o $@ +$(DEST)/portnum.o: $(LIBSRC)/portnum.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/portnum.c -o $@ +$(DEST)/ports.o: $(LIBSRC)/ports.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ports.c -o $@ +$(DEST)/print_toif.o: $(LIBSRC)/print_toif.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/print_toif.c -o $@ +$(DEST)/printactivenat.o: $(LIBSRC)/printactivenat.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printactivenat.c -o $@ +$(DEST)/printaps.o: $(LIBSRC)/printaps.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printaps.c -o $@ +$(DEST)/printbuf.o: $(LIBSRC)/printbuf.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printbuf.c -o $@ +$(DEST)/printfr.o: $(LIBSRC)/printfr.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printfr.c -o $@ +$(DEST)/printfraginfo.o: $(LIBSRC)/printfraginfo.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printfraginfo.c -o $@ +$(DEST)/printhash.o: $(LIBSRC)/printhash.c $(TOP)/ip_fil.h $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhash.c -o $@ +$(DEST)/printhashnode.o: $(LIBSRC)/printhashnode.c $(TOP)/ip_fil.h \ + $(TOP)/ip_htable.h $(TOP)/ip_lookup.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhashnode.c -o $@ +$(DEST)/printip.o: $(LIBSRC)/printip.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printip.c -o $@ +$(DEST)/printpool.o: $(LIBSRC)/printpool.c $(TOP)/ip_fil.h $(TOP)/ip_pool.h + $(CC) $(CCARGS) -c $(LIBSRC)/printpool.c -o $@ +$(DEST)/printpoolnode.o: $(LIBSRC)/printpoolnode.c $(TOP)/ip_fil.h \ + $(TOP)/ip_pool.h $(TOP)/ip_lookup.h + $(CC) $(CCARGS) -c $(LIBSRC)/printpoolnode.c -o $@ +$(DEST)/printhostmap.o: $(LIBSRC)/printhostmap.c $(TOP)/ip_fil.h + $(CC) $(CCARGS) -c $(LIBSRC)/printhostmap.c -o $@ +$(DEST)/printifname.o: $(LIBSRC)/printifname.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printifname.c -o $@ +$(DEST)/printmask.o: $(LIBSRC)/printmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printmask.c -o $@ +$(DEST)/printnat.o: $(LIBSRC)/printnat.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printnat.c -o $@ +$(DEST)/printhostmask.o: $(LIBSRC)/printhostmask.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printhostmask.c -o $@ +$(DEST)/printlog.o: $(LIBSRC)/printlog.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printlog.c -o $@ +$(DEST)/printpacket.o: $(LIBSRC)/printpacket.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printpacket.c -o $@ +$(DEST)/printpacket6.o: $(LIBSRC)/printpacket6.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printpacket6.c -o $@ +$(DEST)/printportcmp.o: $(LIBSRC)/printportcmp.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printportcmp.c -o $@ +$(DEST)/printsbuf.o: $(LIBSRC)/printsbuf.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printsbuf.c -o $@ +$(DEST)/printstate.o: $(LIBSRC)/printstate.c $(INCDEP) $(TOP)/ip_state.h + $(CC) $(CCARGS) -c $(LIBSRC)/printstate.c -o $@ +$(DEST)/printtunable.o: $(LIBSRC)/printtunable.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/printtunable.c -o $@ +$(DEST)/ratoi.o: $(LIBSRC)/ratoi.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ratoi.c -o $@ +$(DEST)/ratoui.o: $(LIBSRC)/ratoui.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/ratoui.c -o $@ +$(DEST)/remove_hash.o: $(LIBSRC)/remove_hash.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_hash.c -o $@ +$(DEST)/remove_hashnode.o: $(LIBSRC)/remove_hashnode.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_hashnode.c -o $@ +$(DEST)/remove_pool.o: $(LIBSRC)/remove_pool.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_pool.c -o $@ +$(DEST)/remove_poolnode.o: $(LIBSRC)/remove_poolnode.c $(INCDEP) \ + $(TOP)/ip_htable.h + $(CC) $(CCARGS) -c $(LIBSRC)/remove_poolnode.c -o $@ +$(DEST)/resetlexer.o: $(LIBSRC)/resetlexer.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/resetlexer.c -o $@ +$(DEST)/rwlock_emul.o: $(LIBSRC)/rwlock_emul.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/rwlock_emul.c -o $@ +$(DEST)/to_interface.o: $(LIBSRC)/to_interface.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/to_interface.c -o $@ +$(DEST)/tcpflags.o: $(LIBSRC)/tcpflags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/tcpflags.c -o $@ +$(DEST)/tcp_flags.o: $(LIBSRC)/tcp_flags.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/tcp_flags.c -o $@ +$(DEST)/var.o: $(LIBSRC)/var.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/var.c -o $@ +$(DEST)/verbose.o: $(LIBSRC)/verbose.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/verbose.c -o $@ +$(DEST)/v6ionames.o: $(LIBSRC)/v6ionames.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/v6ionames.c -o $@ +$(DEST)/v6optvalue.o: $(LIBSRC)/v6optvalue.c $(INCDEP) + $(CC) $(CCARGS) -c $(LIBSRC)/v6optvalue.c -o $@ + +clean-lib: + /bin/rm -f ${LIBOBJS} ${LIB} diff --git a/contrib/ipfilter/lib/addicmp.c b/contrib/ipfilter/lib/addicmp.c new file mode 100644 index 000000000000..a8c1722d46df --- /dev/null +++ b/contrib/ipfilter/lib/addicmp.c @@ -0,0 +1,94 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: addicmp.c,v 1.10.2.1 2004/12/09 19:41:16 darrenr Exp + */ + +#include + +#include "ipf.h" + + +char *icmptypes[MAX_ICMPTYPE + 1] = { + "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", + "redir", (char *)NULL, (char *)NULL, "echo", "routerad", + "routersol", "timex", "paramprob", "timest", "timestrep", + "inforeq", "inforep", "maskreq", "maskrep", "END" +}; + +/* + * set the icmp field to the correct type if "icmp" word is found + */ +int addicmp(cp, fp, linenum) +char ***cp; +struct frentry *fp; +int linenum; +{ + char **t; + int i; + + (*cp)++; + if (!**cp) + return -1; + if (!fp->fr_proto) /* to catch lusers */ + fp->fr_proto = IPPROTO_ICMP; + if (ISDIGIT(***cp)) { + if (!ratoi(**cp, &i, 0, 255)) { + fprintf(stderr, + "%d: Invalid icmp-type (%s) specified\n", + linenum, **cp); + return -1; + } + } else { + for (t = icmptypes, i = 0; ; t++, i++) { + if (!*t) + continue; + if (!strcasecmp("END", *t)) { + i = -1; + break; + } + if (!strcasecmp(*t, **cp)) + break; + } + if (i == -1) { + fprintf(stderr, + "%d: Unknown icmp-type (%s) specified\n", + linenum, **cp); + return -1; + } + } + fp->fr_icmp = (u_short)(i << 8); + fp->fr_icmpm = (u_short)0xff00; + (*cp)++; + if (!**cp) + return 0; + + if (**cp && strcasecmp("code", **cp)) + return 0; + (*cp)++; + if (ISDIGIT(***cp)) { + if (!ratoi(**cp, &i, 0, 255)) { + fprintf(stderr, + "%d: Invalid icmp code (%s) specified\n", + linenum, **cp); + return -1; + } + } else { + i = icmpcode(**cp); + if (i == -1) { + fprintf(stderr, + "%d: Unknown icmp code (%s) specified\n", + linenum, **cp); + return -1; + } + } + i &= 0xff; + fp->fr_icmp |= (u_short)i; + fp->fr_icmpm = (u_short)0xffff; + (*cp)++; + return 0; +} diff --git a/contrib/ipfilter/lib/addipopt.c b/contrib/ipfilter/lib/addipopt.c new file mode 100644 index 000000000000..23f44273eb5b --- /dev/null +++ b/contrib/ipfilter/lib/addipopt.c @@ -0,0 +1,67 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: addipopt.c,v 1.7 2002/01/28 06:50:45 darrenr Exp + */ + +#include "ipf.h" + + +int addipopt(op, io, len, class) +char *op; +struct ipopt_names *io; +int len; +char *class; +{ + int olen = len; + struct in_addr ipadr; + u_short val; + u_char lvl; + char *s; + + if ((len + io->on_siz) > 48) { + fprintf(stderr, "options too long\n"); + return 0; + } + len += io->on_siz; + *op++ = io->on_value; + if (io->on_siz > 1) { + s = op; + *op++ = io->on_siz; + *op++ = IPOPT_MINOFF; + + if (class) { + switch (io->on_value) + { + case IPOPT_SECURITY : + lvl = seclevel(class); + *(op - 1) = lvl; + break; + case IPOPT_LSRR : + case IPOPT_SSRR : + ipadr.s_addr = inet_addr(class); + s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4; + bcopy((char *)&ipadr, op, sizeof(ipadr)); + break; + case IPOPT_SATID : + val = atoi(class); + bcopy((char *)&val, op, 2); + break; + } + } + + op += io->on_siz - 3; + if (len & 3) { + *op++ = IPOPT_NOP; + len++; + } + } + if (opts & OPT_DEBUG) + fprintf(stderr, "bo: %s %d %#x: %d\n", + io->on_name, io->on_value, io->on_bit, len); + return len - olen; +} diff --git a/contrib/ipfilter/lib/addkeep.c b/contrib/ipfilter/lib/addkeep.c new file mode 100644 index 000000000000..3f20fb424201 --- /dev/null +++ b/contrib/ipfilter/lib/addkeep.c @@ -0,0 +1,86 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: addkeep.c,v 1.12 2003/12/01 01:59:42 darrenr Exp + */ + +#include "ipf.h" + + +/* + * Parses "keep state" and "keep frags" stuff on the end of a line. + */ +int addkeep(cp, fp, linenum) +char ***cp; +struct frentry *fp; +int linenum; +{ + char *s; + + (*cp)++; + if (!**cp) { + fprintf(stderr, "%d: Missing state/frag after keep\n", + linenum); + return -1; + } + + if (!strcasecmp(**cp, "state")) { + fp->fr_flags |= FR_KEEPSTATE; + (*cp)++; + if (**cp && !strcasecmp(**cp, "limit")) { + (*cp)++; + fp->fr_statemax = atoi(**cp); + (*cp)++; + } + if (**cp && !strcasecmp(**cp, "scan")) { + (*cp)++; + if (!strcmp(**cp, "*")) { + fp->fr_isc = NULL; + fp->fr_isctag[0] = '\0'; + } else { + strncpy(fp->fr_isctag, **cp, + sizeof(fp->fr_isctag)); + fp->fr_isctag[sizeof(fp->fr_isctag)-1] = '\0'; + fp->fr_isc = NULL; + } + (*cp)++; + } else + fp->fr_isc = (struct ipscan *)-1; + } else if (!strncasecmp(**cp, "frag", 4)) { + fp->fr_flags |= FR_KEEPFRAG; + (*cp)++; + } else if (!strcasecmp(**cp, "state-age")) { + if (fp->fr_ip.fi_p == IPPROTO_TCP) { + fprintf(stderr, "%d: cannot use state-age with tcp\n", + linenum); + return -1; + } + if ((fp->fr_flags & FR_KEEPSTATE) == 0) { + fprintf(stderr, "%d: state-age with no 'keep state'\n", + linenum); + return -1; + } + (*cp)++; + if (!**cp) { + fprintf(stderr, "%d: state-age with no arg\n", + linenum); + return -1; + } + fp->fr_age[0] = atoi(**cp); + s = strchr(**cp, '/'); + if (s != NULL) { + s++; + fp->fr_age[1] = atoi(s); + } else + fp->fr_age[1] = fp->fr_age[0]; + } else { + fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n", + linenum, **cp); + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/bcopywrap.c b/contrib/ipfilter/lib/bcopywrap.c new file mode 100644 index 000000000000..939137ba2846 --- /dev/null +++ b/contrib/ipfilter/lib/bcopywrap.c @@ -0,0 +1,12 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int bcopywrap(from, to, size) +void *from, *to; +size_t size; +{ + bcopy((caddr_t)from, (caddr_t)to, size); + return 0; +} + diff --git a/contrib/ipfilter/lib/binprint.c b/contrib/ipfilter/lib/binprint.c new file mode 100644 index 000000000000..afa491008fa1 --- /dev/null +++ b/contrib/ipfilter/lib/binprint.c @@ -0,0 +1,31 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: binprint.c,v 1.8 2002/05/14 15:18:56 darrenr Exp + */ + +#include "ipf.h" + + +void binprint(ptr, size) +void *ptr; +size_t size; +{ + u_char *s; + int i, j; + + for (i = size, j = 0, s = (u_char *)ptr; i; i--, s++) { + j++; + printf("%02x ", *s); + if (j == 16) { + printf("\n"); + j = 0; + } + } + putchar('\n'); + (void)fflush(stdout); +} diff --git a/contrib/ipfilter/lib/buildopts.c b/contrib/ipfilter/lib/buildopts.c new file mode 100644 index 000000000000..a35649bf3c74 --- /dev/null +++ b/contrib/ipfilter/lib/buildopts.c @@ -0,0 +1,44 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: buildopts.c,v 1.6 2002/01/28 06:50:45 darrenr Exp + */ + +#include "ipf.h" + + +u_32_t buildopts(cp, op, len) +char *cp, *op; +int len; +{ + struct ipopt_names *io; + u_32_t msk = 0; + char *s, *t; + int inc; + + for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { + if ((t = strchr(s, '='))) + *t++ = '\0'; + for (io = ionames; io->on_name; io++) { + if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) + continue; + if ((inc = addipopt(op, io, len, t))) { + op += inc; + len += inc; + } + msk |= io->on_bit; + break; + } + if (!io->on_name) { + fprintf(stderr, "unknown IP option name %s\n", s); + return 0; + } + } + *op++ = IPOPT_EOL; + len++; + return len; +} diff --git a/contrib/ipfilter/lib/checkrev.c b/contrib/ipfilter/lib/checkrev.c new file mode 100644 index 000000000000..28032ce81f25 --- /dev/null +++ b/contrib/ipfilter/lib/checkrev.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: checkrev.c,v 1.12.2.1 2004/03/09 14:44:39 darrenr Exp + */ + +#include +#include + +#include "ipf.h" +#include "netinet/ipl.h" + +int checkrev(ipfname) +char *ipfname; +{ + static int vfd = -1; + struct friostat fio, *fiop = &fio; + ipfobj_t ipfo; + + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(*fiop); + ipfo.ipfo_ptr = (void *)fiop; + ipfo.ipfo_type = IPFOBJ_IPFSTAT; + + if ((vfd == -1) && ((vfd = open(ipfname, O_RDONLY)) == -1)) { + perror("open device"); + return -1; + } + + if (ioctl(vfd, SIOCGETFS, &ipfo)) { + perror("ioctl(SIOCGETFS)"); + close(vfd); + vfd = -1; + return -1; + } + + if (strncmp(IPL_VERSION, fio.f_version, sizeof(fio.f_version))) { + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/count4bits.c b/contrib/ipfilter/lib/count4bits.c new file mode 100644 index 000000000000..0f2187fde14c --- /dev/null +++ b/contrib/ipfilter/lib/count4bits.c @@ -0,0 +1,40 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: count4bits.c,v 1.1 2002/06/15 04:46:39 darrenr Exp + */ + +#include "ipf.h" + + +/* + * 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_int ip; +{ + int cnt = 0, i, j; + u_int ipn; + + ip = ipn = ntohl(ip); + for (i = 32; i; i--, ipn *= 2) + if (ipn & 0x80000000) + cnt++; + else + break; + ipn = 0; + for (i = 32, j = cnt; i; i--, j--) { + ipn *= 2; + if (j > 0) + ipn++; + } + if (ipn == ip) + return cnt; + return -1; +} diff --git a/contrib/ipfilter/lib/count6bits.c b/contrib/ipfilter/lib/count6bits.c new file mode 100644 index 000000000000..bd4e9f80d23d --- /dev/null +++ b/contrib/ipfilter/lib/count6bits.c @@ -0,0 +1,29 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: count6bits.c,v 1.4 2001/06/09 17:09:23 darrenr Exp + */ + +#include "ipf.h" + + +int count6bits(msk) +u_32_t *msk; +{ + int i = 0, k; + u_32_t j; + + for (k = 3; k >= 0; k--) + if (msk[k] == 0xffffffff) + i += 32; + else { + for (j = msk[k]; j; j <<= 1) + if (j & 0x80000000) + i++; + } + return i; +} diff --git a/contrib/ipfilter/lib/debug.c b/contrib/ipfilter/lib/debug.c new file mode 100644 index 000000000000..151022256478 --- /dev/null +++ b/contrib/ipfilter/lib/debug.c @@ -0,0 +1,37 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: debug.c,v 1.6 2001/06/09 17:09:24 darrenr Exp + */ + +#if defined(__STDC__) +# include +#else +# include +#endif +#include + +#include "ipt.h" +#include "opts.h" + + +#ifdef __STDC__ +void debug(char *fmt, ...) +#else +void debug(fmt, va_alist) +char *fmt; +va_dcl +#endif +{ + va_list pvar; + + va_start(pvar, fmt); + + if (opts & OPT_DEBUG) + vprintf(fmt, pvar); + va_end(pvar); +} diff --git a/contrib/ipfilter/lib/extras.c b/contrib/ipfilter/lib/extras.c new file mode 100644 index 000000000000..0f7f39f1995d --- /dev/null +++ b/contrib/ipfilter/lib/extras.c @@ -0,0 +1,114 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: extras.c,v 1.12 2002/07/13 12:06:49 darrenr Exp + */ + +#include "ipf.h" + + +/* + * deal with extra bits on end of the line + */ +int extras(cp, fr, linenum) +char ***cp; +struct frentry *fr; +int linenum; +{ + u_short secmsk; + u_long opts; + int notopt; + + opts = 0; + secmsk = 0; + notopt = 0; + (*cp)++; + if (!**cp) + return -1; + + while (**cp) { + if (!strcasecmp(**cp, "not") || !strcasecmp(**cp, "no")) { + notopt = 1; + (*cp)++; + continue; + } else if (!strncasecmp(**cp, "ipopt", 5)) { + if (!notopt) + fr->fr_flx |= FI_OPTIONS; + fr->fr_mflx |= FI_OPTIONS; + goto nextopt; + } else if (!strcasecmp(**cp, "lowttl")) { + if (!notopt) + fr->fr_flx |= FI_LOWTTL; + fr->fr_mflx |= FI_LOWTTL; + goto nextopt; + } else if (!strcasecmp(**cp, "bad-src")) { + if (!notopt) + fr->fr_flx |= FI_BADSRC; + fr->fr_mflx |= FI_BADSRC; + goto nextopt; + } else if (!strncasecmp(**cp, "mbcast", 6)) { + if (!notopt) + fr->fr_flx |= FI_MBCAST; + fr->fr_mflx |= FI_MBCAST; + goto nextopt; + } else if (!strncasecmp(**cp, "nat", 3)) { + if (!notopt) + fr->fr_flx |= FI_NATED; + fr->fr_mflx |= FI_NATED; + goto nextopt; + } else if (!strncasecmp(**cp, "frag", 4)) { + if (!notopt) + fr->fr_flx |= FI_FRAG; + fr->fr_mflx |= FI_FRAG; + goto nextopt; + } else if (!strncasecmp(**cp, "opt", 3)) { + if (!*(*cp + 1)) { + fprintf(stderr, "%d: opt missing arguements\n", + linenum); + return -1; + } + (*cp)++; + if (!(opts = optname(cp, &secmsk, linenum))) + return -1; + + if (notopt) { + if (!secmsk) { + fr->fr_optmask |= opts; + } else { + fr->fr_optmask |= (opts & ~0x0100); + fr->fr_secmask |= secmsk; + } + fr->fr_secbits &= ~secmsk; + fr->fr_optbits &= ~opts; + } else { + fr->fr_optmask |= opts; + fr->fr_secmask |= secmsk; + fr->fr_optbits |= opts; + fr->fr_secbits |= secmsk; + } + } else if (!strncasecmp(**cp, "short", 5)) { + if (fr->fr_tcpf) { + fprintf(stderr, + "%d: short cannot be used with TCP flags\n", + linenum); + return -1; + } + + if (!notopt) + fr->fr_flx |= FI_SHORT; + fr->fr_mflx |= FI_SHORT; + goto nextopt; + } else + return -1; +nextopt: + notopt = 0; + opts = 0; + secmsk = 0; + (*cp)++; + } + return 0; +} diff --git a/contrib/ipfilter/lib/facpri.c b/contrib/ipfilter/lib/facpri.c new file mode 100644 index 000000000000..1e35ea9dfe71 --- /dev/null +++ b/contrib/ipfilter/lib/facpri.c @@ -0,0 +1,153 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp + */ + +#include +#include +#include +#include +#if !defined(__SVR4) && !defined(__svr4__) +#include +#endif +#include +#include +#include +#include +#include "facpri.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: facpri.c,v 1.6 2003/12/01 01:59:43 darrenr Exp"; +#endif + + +typedef struct table { + char *name; + int value; +} table_t; + +table_t facs[] = { + { "kern", LOG_KERN }, { "user", LOG_USER }, + { "mail", LOG_MAIL }, { "daemon", LOG_DAEMON }, + { "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG }, + { "lpr", LOG_LPR }, { "news", LOG_NEWS }, + { "uucp", LOG_UUCP }, +#if LOG_CRON == LOG_CRON2 + { "cron2", LOG_CRON1 }, +#else + { "cron", LOG_CRON1 }, +#endif +#ifdef LOG_FTP + { "ftp", LOG_FTP }, +#endif +#ifdef LOG_AUTHPRIV + { "authpriv", LOG_AUTHPRIV }, +#endif +#ifdef LOG_AUDIT + { "audit", LOG_AUDIT }, +#endif +#ifdef LOG_LFMT + { "logalert", LOG_LFMT }, +#endif +#if LOG_CRON == LOG_CRON1 + { "cron", LOG_CRON2 }, +#else + { "cron2", LOG_CRON2 }, +#endif +#ifdef LOG_SECURITY + { "security", LOG_SECURITY }, +#endif + { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, + { NULL, 0 } +}; + + +/* + * map a facility number to its name + */ +char * +fac_toname(facpri) + int facpri; +{ + int i, j, fac; + + fac = facpri & LOG_FACMASK; + j = fac >> 3; + if (j < 24) { + if (facs[j].value == fac) + return facs[j].name; + for (i = 0; facs[i].name; i++) + if (fac == facs[i].value) + return facs[i].name; + } + + return NULL; +} + + +/* + * map a facility name to its number + */ +int +fac_findname(name) + char *name; +{ + int i; + + for (i = 0; facs[i].name; i++) + if (!strcmp(facs[i].name, name)) + return facs[i].value; + return -1; +} + + +table_t pris[] = { + { "emerg", LOG_EMERG }, { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, { "err", LOG_ERR }, + { "warn", LOG_WARNING }, { "notice", LOG_NOTICE }, + { "info", LOG_INFO }, { "debug", LOG_DEBUG }, + { NULL, 0 } +}; + + +/* + * map a priority name to its number + */ +int +pri_findname(name) + char *name; +{ + int i; + + for (i = 0; pris[i].name; i++) + if (!strcmp(pris[i].name, name)) + return pris[i].value; + return -1; +} + + +/* + * map a priority number to its name + */ +char * +pri_toname(facpri) + int facpri; +{ + int i, pri; + + pri = facpri & LOG_PRIMASK; + if (pris[pri].value == pri) + return pris[pri].name; + for (i = 0; pris[i].name; i++) + if (pri == pris[i].value) + return pris[i].name; + return NULL; +} diff --git a/contrib/ipfilter/lib/facpri.h b/contrib/ipfilter/lib/facpri.h new file mode 100644 index 000000000000..e8eef2ba283a --- /dev/null +++ b/contrib/ipfilter/lib/facpri.h @@ -0,0 +1,43 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1999-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: facpri.h,v 1.3 2001/06/09 17:19:50 darrenr Exp + */ + +#ifndef __FACPRI_H__ +#define __FACPRI_H__ + +#ifndef __P +# define P_DEF +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +extern char *fac_toname __P((int)); +extern int fac_findname __P((char *)); + +extern char *pri_toname __P((int)); +extern int pri_findname __P((char *)); + +#ifdef P_DEF +# undef __P +# undef P_DEF +#endif + +#if LOG_CRON == (9<<3) +# define LOG_CRON1 LOG_CRON +# define LOG_CRON2 (15<<3) +#endif +#if LOG_CRON == (15<<3) +# define LOG_CRON1 (9<<3) +# define LOG_CRON2 LOG_CRON +#endif + +#endif /* __FACPRI_H__ */ diff --git a/contrib/ipfilter/lib/fill6bits.c b/contrib/ipfilter/lib/fill6bits.c new file mode 100644 index 000000000000..8f23a6f918a7 --- /dev/null +++ b/contrib/ipfilter/lib/fill6bits.c @@ -0,0 +1,48 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: fill6bits.c,v 1.5 2002/03/27 15:09:57 darrenr Exp + */ + +#include "ipf.h" + + +void fill6bits(bits, msk) +int bits; +u_int *msk; +{ + if (bits == 0) { + msk[0] = 0; + msk[1] = 0; + msk[2] = 0; + msk[3] = 0; + return; + } + + msk[0] = 0xffffffff; + msk[1] = 0xffffffff; + msk[2] = 0xffffffff; + msk[3] = 0xffffffff; + + if (bits == 128) + return; + if (bits > 96) { + msk[3] = htonl(msk[3] << (128 - bits)); + } else if (bits > 64) { + msk[3] = 0; + msk[2] = htonl(msk[2] << (96 - bits)); + } else if (bits > 32) { + msk[3] = 0; + msk[2] = 0; + msk[1] = htonl(msk[1] << (64 - bits)); + } else { + msk[3] = 0; + msk[2] = 0; + msk[1] = 0; + msk[0] = htonl(msk[0] << (32 - bits)); + } +} diff --git a/contrib/ipfilter/lib/flags.c b/contrib/ipfilter/lib/flags.c new file mode 100644 index 000000000000..df6645d1a4dd --- /dev/null +++ b/contrib/ipfilter/lib/flags.c @@ -0,0 +1,25 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: flags.c,v 1.4 2002/11/02 07:16:36 darrenr Exp + */ + +#include "ipf.h" + +/* + * ECN is a new addition to TCP - RFC 2481 + */ +#ifndef TH_ECN +# define TH_ECN 0x40 +#endif +#ifndef TH_CWR +# define TH_CWR 0x80 +#endif + +char flagset[] = "FSRPAUEC"; +u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG, + TH_ECN, TH_CWR }; diff --git a/contrib/ipfilter/lib/genmask.c b/contrib/ipfilter/lib/genmask.c new file mode 100644 index 000000000000..06f64043070f --- /dev/null +++ b/contrib/ipfilter/lib/genmask.c @@ -0,0 +1,56 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: genmask.c,v 1.7 2003/11/11 13:40:15 darrenr Exp + */ + +#include "ipf.h" + + +int genmask(msk, mskp) +char *msk; +u_32_t *mskp; +{ + char *endptr = 0L; + int bits; + + if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) { + /* possibly of the form xxx.xxx.xxx.xxx + * or 0xYYYYYYYY */ +#ifdef USE_INET6 + if (use_inet6) { + if (inet_pton(AF_INET6, msk, mskp) != 1) + return -1; + } else +#endif + if (inet_aton(msk, (struct in_addr *)mskp) == 0) + return -1; + } else { + /* + * set x most significant bits + */ + bits = (int)strtol(msk, &endptr, 0); +#ifdef USE_INET6 + if ((*endptr != '\0') || + ((bits > 32) && !use_inet6) || (bits < 0) || + ((bits > 128) && use_inet6)) +#else + if (*endptr != '\0' || bits > 32 || bits < 0) +#endif + return -1; +#ifdef USE_INET6 + if (use_inet6) + fill6bits(bits, mskp); + else +#endif + if (bits == 0) + *mskp = 0; + else + *mskp = htonl(0xffffffff << (32 - bits)); + } + return 0; +} diff --git a/contrib/ipfilter/lib/gethost.c b/contrib/ipfilter/lib/gethost.c new file mode 100644 index 000000000000..a03168a3f73e --- /dev/null +++ b/contrib/ipfilter/lib/gethost.c @@ -0,0 +1,36 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int gethost(name, hostp) +char *name; +u_32_t *hostp; +{ + struct hostent *h; + struct netent *n; + u_32_t addr; + + if (!strcmp(name, "test.host.dots")) { + *hostp = htonl(0xfedcba98); + return 0; + } + + if (!strcmp(name, "")) + name = thishost; + + h = gethostbyname(name); + if (h != NULL) { + if ((h->h_addr != NULL) && (h->h_length == sizeof(addr))) { + bcopy(h->h_addr, (char *)&addr, sizeof(addr)); + *hostp = addr; + return 0; + } + } + + n = getnetbyname(name); + if (n != NULL) { + *hostp = (u_32_t)htonl(n->n_net & 0xffffffff); + return 0; + } + return -1; +} diff --git a/contrib/ipfilter/lib/getifname.c b/contrib/ipfilter/lib/getifname.c new file mode 100644 index 000000000000..94c9c9c7e4f0 --- /dev/null +++ b/contrib/ipfilter/lib/getifname.c @@ -0,0 +1,76 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#include "kmem.h" + +/* + * Given a pointer to an interface in the kernel, return a pointer to a + * string which is the interface name. + */ +char *getifname(ptr) +struct ifnet *ptr; +{ +#if SOLARIS || defined(__hpux) +# if SOLARIS +# include +# include +# endif +# ifdef __hpux +# include "compat.h" +# endif +# include "../pfil/qif.h" + char *ifname; + qif_t qif; + + if ((void *)ptr == (void *)-1) + return "!"; + if (ptr == NULL) + return "-"; + + if (kmemcpy((char *)&qif, (u_long)ptr, sizeof(qif)) == -1) + return "X"; + ifname = strdup(qif.qf_name); + if ((ifname != NULL) && (*ifname == '\0')) { + free(ifname); + return "!"; + } + return ifname; +#else +# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + defined(__OpenBSD__) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) +#else + char buf[32]; + int len; +# endif + struct ifnet netif; + + if ((void *)ptr == (void *)-1) + return "!"; + if (ptr == NULL) + return "-"; + + if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1) + return "X"; +# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ + defined(__OpenBSD__) || defined(linux) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) + return strdup(netif.if_xname); +# else + if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1) + return "X"; + if (netif.if_unit < 10) + len = 2; + else if (netif.if_unit < 1000) + len = 3; + else if (netif.if_unit < 10000) + len = 4; + else + len = 5; + buf[sizeof(buf) - len] = '\0'; + sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000); + return strdup(buf); +# endif +#endif +} diff --git a/contrib/ipfilter/lib/getline.c b/contrib/ipfilter/lib/getline.c new file mode 100644 index 000000000000..61c00ba3b933 --- /dev/null +++ b/contrib/ipfilter/lib/getline.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: getline.c,v 1.3 2001/06/09 17:09:24 darrenr Exp + */ + +#include +#if !defined(__SVR4) && !defined(__GNUC__) +#include +#endif +#include +#include "ipf.h" + + +/* + * Similar to fgets(3) but can handle '\\' and NL is converted to NUL. + * Returns NULL if error occured, EOF encounterd or input line is too long. + */ +char *getline(str, size, file, linenum) +register char *str; +size_t size; +FILE *file; +int *linenum; +{ + char *p; + int s, len; + + do { + for (p = str, s = size;; p += (len - 1), s -= (len - 1)) { + /* + * if an error occured, EOF was encounterd, or there + * was no room to put NUL, return NULL. + */ + if (fgets(p, s, file) == NULL) + return (NULL); + len = strlen(p); + if (p[len - 1] != '\n') { + p[len] = '\0'; + break; + } + (*linenum)++; + p[len - 1] = '\0'; + if (len < 2 || p[len - 2] != '\\') + break; + else + /* + * Convert '\\' to a space so words don't + * run together + */ + p[len - 2] = ' '; + } + } while (*str == '\0'); + return (str); +} diff --git a/contrib/ipfilter/lib/getnattype.c b/contrib/ipfilter/lib/getnattype.c new file mode 100644 index 000000000000..c783d6fce813 --- /dev/null +++ b/contrib/ipfilter/lib/getnattype.c @@ -0,0 +1,54 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ +#include "ipf.h" +#include "kmem.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: getnattype.c,v 1.3 2004/01/17 17:26:07 darrenr Exp"; +#endif + + +/* + * Get a nat filter type given its kernel address. + */ +char *getnattype(ipnat) +ipnat_t *ipnat; +{ + static char unknownbuf[20]; + ipnat_t ipnatbuff; + char *which; + + if (!ipnat) + return "???"; + if (kmemcpy((char *)&ipnatbuff, (long)ipnat, sizeof(ipnatbuff))) + return "!!!"; + + switch (ipnatbuff.in_redir) + { + case NAT_MAP : + which = "MAP"; + break; + case NAT_MAPBLK : + which = "MAP-BLOCK"; + break; + case NAT_REDIRECT : + which = "RDR"; + break; + case NAT_BIMAP : + which = "BIMAP"; + break; + default : + sprintf(unknownbuf, "unknown(%04x)", + ipnatbuff.in_redir & 0xffffffff); + which = unknownbuf; + break; + } + return which; +} diff --git a/contrib/ipfilter/lib/getport.c b/contrib/ipfilter/lib/getport.c new file mode 100644 index 000000000000..7cf903d8fe25 --- /dev/null +++ b/contrib/ipfilter/lib/getport.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int getport(fr, name, port) +frentry_t *fr; +char *name; +u_short *port; +{ + struct protoent *p; + struct servent *s; + u_short p1; + + if (fr == NULL || fr->fr_type != FR_T_IPF) { + s = getservbyname(name, NULL); + if (s != NULL) { + *port = s->s_port; + return 0; + } + return -1; + } + + if ((fr->fr_flx & FI_TCPUDP) != 0) { + /* + * If a rule is "tcp/udp" then check that both TCP and UDP + * mappings for this protocol name match ports. + */ + s = getservbyname(name, "tcp"); + if (s == NULL) + return -1; + p1 = s->s_port; + s = getservbyname(name, "udp"); + if (s == NULL || s->s_port != p1) + return -1; + *port = p1; + return 0; + } + + p = getprotobynumber(fr->fr_proto); + s = getservbyname(name, p ? p->p_name : NULL); + if (s != NULL) { + *port = s->s_port; + return 0; + } + return -1; +} diff --git a/contrib/ipfilter/lib/getportproto.c b/contrib/ipfilter/lib/getportproto.c new file mode 100644 index 000000000000..17efa4361984 --- /dev/null +++ b/contrib/ipfilter/lib/getportproto.c @@ -0,0 +1,32 @@ +/* $NetBSD$ */ + +#include +#include "ipf.h" + +int getportproto(name, proto) +char *name; +int proto; +{ + struct servent *s; + struct protoent *p; + + if (ISDIGIT(*name)) { + int number; + char *s; + + for (s = name; *s != '\0'; s++) + if (!ISDIGIT(*s)) + return -1; + + number = atoi(name); + if (number < 0 || number > 65535) + return -1; + return htons(number); + } + + p = getprotobynumber(proto); + s = getservbyname(name, p ? p->p_name : NULL); + if (s != NULL) + return s->s_port; + return -1; +} diff --git a/contrib/ipfilter/lib/getproto.c b/contrib/ipfilter/lib/getproto.c new file mode 100644 index 000000000000..c75f13742d10 --- /dev/null +++ b/contrib/ipfilter/lib/getproto.c @@ -0,0 +1,21 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int getproto(name) +char *name; +{ + struct protoent *p; + char *s; + + for (s = name; *s != '\0'; s++) + if (!ISDIGIT(*s)) + break; + if (*s == '\0') + return atoi(name); + + p = getprotobyname(name); + if (p != NULL) + return p->p_proto; + return -1; +} diff --git a/contrib/ipfilter/lib/getsumd.c b/contrib/ipfilter/lib/getsumd.c new file mode 100644 index 000000000000..11ecc5734596 --- /dev/null +++ b/contrib/ipfilter/lib/getsumd.c @@ -0,0 +1,15 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +char *getsumd(sum) +u_32_t sum; +{ + static char sumdbuf[17]; + + if (sum & NAT_HW_CKSUM) + sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff); + else + sprintf(sumdbuf, "%#0x", sum); + return sumdbuf; +} diff --git a/contrib/ipfilter/lib/hexdump.c b/contrib/ipfilter/lib/hexdump.c new file mode 100644 index 000000000000..4eb3b9ad8f42 --- /dev/null +++ b/contrib/ipfilter/lib/hexdump.c @@ -0,0 +1,30 @@ +/* $NetBSD$ */ + +#include + +#include "ipf.h" + +void hexdump(out, addr, len, ascii) +FILE *out; +void *addr; +int len, ascii; +{ + FILE *fpout; + u_char *s, *t; + int i; + + fpout = out ? out : stdout; + for (i = 0, s = addr; i < len; i++, s++) { + fprintf(fpout, "%02x", *s); + if (i % 16 == 15) { + if (ascii != 0) { + fputc('\t', fpout); + for (t = s - 15; t<= s; t++) + fputc(ISPRINT(*t) ? *t : '.', fpout); + } + fputc('\n', fpout); + } else if (i % 4 == 3) { + fputc(' ', fpout); + } + } +} diff --git a/contrib/ipfilter/lib/hostmask.c b/contrib/ipfilter/lib/hostmask.c new file mode 100644 index 000000000000..67755f8383dc --- /dev/null +++ b/contrib/ipfilter/lib/hostmask.c @@ -0,0 +1,95 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: hostmask.c,v 1.10 2002/01/28 06:50:46 darrenr Exp + */ + +#include "ipf.h" + + +/* + * returns -1 if neither "hostmask/num" or "hostmask mask addr" are + * found in the line segments, there is an error processing this information, + * or there is an error processing ports information. + */ +int hostmask(seg, proto, ifname, sa, msk, linenum) +char ***seg, *proto, *ifname; +u_32_t *sa, *msk; +int linenum; +{ + struct in_addr maskaddr; + char *s; + + if ((s = strchr(**seg, '='))) { + *s++ = '\0'; + if (!strcmp(**seg, "pool")) { + *sa = atoi(s); + return 1; + } + } + + /* + * is it possibly hostname/num ? + */ + if ((s = strchr(**seg, '/')) || + ((s = strchr(**seg, ':')) && !strchr(s + 1, ':'))) { + *s++ ='\0'; + if (genmask(s, msk) == -1) { + fprintf(stderr, "%d: bad mask (%s)\n", linenum, s); + return -1; + } + if (hostnum(sa, **seg, linenum, ifname) == -1) { + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; + } + *sa &= *msk; + (*seg)++; + return 0; + } + + /* + * look for extra segments if "mask" found in right spot + */ + if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) { + if (hostnum(sa, **seg, linenum, ifname) == -1) { + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; + } + (*seg)++; + (*seg)++; + if (inet_aton(**seg, &maskaddr) == 0) { + fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg); + return -1; + } + *msk = maskaddr.s_addr; + (*seg)++; + *sa &= *msk; + return 0; + } + + if (**seg) { + u_32_t k; + + if (hostnum(sa, **seg, linenum, ifname) == -1) { + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; + } + (*seg)++; + k = *sa ? 0xffffffff : 0; +#ifdef USE_INET6 + if (use_inet6) { + msk[1] = k; + msk[2] = k; + msk[3] = k; + } +#endif + *msk = k; + return 0; + } + fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); + return -1; +} diff --git a/contrib/ipfilter/lib/hostname.c b/contrib/ipfilter/lib/hostname.c new file mode 100644 index 000000000000..a0109dafb939 --- /dev/null +++ b/contrib/ipfilter/lib/hostname.c @@ -0,0 +1,51 @@ +/* $NetBSD$ */ + + +#include "ipf.h" + +char *hostname(v, ip) +int v; +void *ip; +{ + static char hostbuf[MAXHOSTNAMELEN+1]; + struct hostent *hp; + struct in_addr ipa; + struct netent *np; + + if (v == 4) { + ipa.s_addr = *(u_32_t *)ip; + if (ipa.s_addr == htonl(0xfedcba98)) + return "test.host.dots"; + } + + if ((opts & OPT_NORESOLVE) == 0) { + if (v == 4) { + hp = gethostbyaddr(ip, 4, AF_INET); + if (hp != NULL && hp->h_name != NULL && + *hp->h_name != '\0') { + strncpy(hostbuf, hp->h_name, sizeof(hostbuf)); + hostbuf[sizeof(hostbuf) - 1] = '\0'; + return hostbuf; + } + + np = getnetbyaddr(ipa.s_addr, AF_INET); + if (np != NULL && np->n_name != NULL && + *np->n_name != '\0') { + strncpy(hostbuf, np->n_name, sizeof(hostbuf)); + hostbuf[sizeof(hostbuf) - 1] = '\0'; + return hostbuf; + } + } + } + + if (v == 4) { + return inet_ntoa(ipa); + } +#ifdef USE_INET6 + (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); + hostbuf[MAXHOSTNAMELEN] = '\0'; + return hostbuf; +#else + return "IPv6"; +#endif +} diff --git a/contrib/ipfilter/lib/hostnum.c b/contrib/ipfilter/lib/hostnum.c new file mode 100644 index 000000000000..c62e4a10dbcb --- /dev/null +++ b/contrib/ipfilter/lib/hostnum.c @@ -0,0 +1,49 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: hostnum.c,v 1.10.2.1 2004/12/09 19:41:20 darrenr Exp + */ + +#include + +#include "ipf.h" + + +/* + * returns an ip address as a long var as a result of either a DNS lookup or + * straight inet_addr() call + */ +int hostnum(ipa, host, linenum, ifname) +u_32_t *ipa; +char *host; +int linenum; +char *ifname; +{ + struct in_addr ip; + + if (!strcasecmp("any", host) || + (ifname && *ifname && !strcasecmp(ifname, host))) + return 0; + +#ifdef USE_INET6 + if (use_inet6) { + if (inet_pton(AF_INET6, host, ipa) == 1) + return 0; + else + return -1; + } +#endif + if (ISDIGIT(*host) && inet_aton(host, &ip)) { + *ipa = ip.s_addr; + return 0; + } + + if (!strcasecmp("", host)) + host = thishost; + + return gethost(host, ipa); +} diff --git a/contrib/ipfilter/lib/icmpcode.c b/contrib/ipfilter/lib/icmpcode.c new file mode 100644 index 000000000000..17e1ba4dfb1c --- /dev/null +++ b/contrib/ipfilter/lib/icmpcode.c @@ -0,0 +1,49 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: icmpcode.c,v 1.7.2.1 2004/12/09 19:41:20 darrenr Exp + */ + +#include + +#include "ipf.h" + +#ifndef MIN +# define MIN(a,b) ((a) > (b) ? (b) : (a)) +#endif + + +char *icmpcodes[MAX_ICMPCODE + 1] = { + "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail", + "net-unk", "host-unk", "isolate", "net-prohib", "host-prohib", + "net-tos", "host-tos", "filter-prohib", "host-preced", "preced-cutoff", + NULL }; + +/* + * Return the number for the associated ICMP unreachable code. + */ +int icmpcode(str) +char *str; +{ + char *s; + int i, len; + + if ((s = strrchr(str, ')'))) + *s = '\0'; + if (ISDIGIT(*str)) { + if (!ratoi(str, &i, 0, 255)) + return -1; + else + return i; + } + len = strlen(str); + for (i = 0; icmpcodes[i]; i++) + if (!strncasecmp(str, icmpcodes[i], MIN(len, + strlen(icmpcodes[i])) )) + return i; + return -1; +} diff --git a/contrib/ipfilter/lib/inet_addr.c b/contrib/ipfilter/lib/inet_addr.c new file mode 100644 index 000000000000..5ccf6a96a0b8 --- /dev/null +++ b/contrib/ipfilter/lib/inet_addr.c @@ -0,0 +1,210 @@ +/* $NetBSD$ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#if !defined(lint) +static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static const char rcsid[] = "@(#)Id: inet_addr.c,v 1.8.2.3 2004/12/09 19:41:20 darrenr Exp"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif +#ifndef linux +int inet_aton __P((const char *, struct in_addr *)); + +/* + * 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)) + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(cp, addr) + register const char *cp; + struct in_addr *addr; +{ + register u_long val; + register int base, n; + register char c; + u_int parts[4]; + register u_int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!ISDIGIT(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (ISASCII(c) && ISDIGIT(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && ISASCII(c) && ISXDIGIT(c)) { + val = (val << 4) | + (c + 10 - (ISLOWER(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!ISASCII(c) || !ISSPACE(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} +#endif + +/* these are compatibility routines, not needed on recent BSD releases */ + +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +#if 0 +inet_addr(cp) + const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (0xffffffff); +} +#endif diff --git a/contrib/ipfilter/lib/initparse.c b/contrib/ipfilter/lib/initparse.c new file mode 100644 index 000000000000..676774c48b03 --- /dev/null +++ b/contrib/ipfilter/lib/initparse.c @@ -0,0 +1,20 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: initparse.c,v 1.6 2002/01/28 06:50:46 darrenr Exp + */ +#include "ipf.h" + + +char thishost[MAXHOSTNAMELEN]; + + +void initparse __P((void)) +{ + gethostname(thishost, sizeof(thishost)); + thishost[sizeof(thishost) - 1] = '\0'; +} diff --git a/contrib/ipfilter/lib/ionames.c b/contrib/ipfilter/lib/ionames.c new file mode 100644 index 000000000000..9e4602b8764e --- /dev/null +++ b/contrib/ipfilter/lib/ionames.c @@ -0,0 +1,40 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ionames.c,v 1.7 2002/01/28 06:50:46 darrenr Exp + */ +#include "ipf.h" + + +struct ipopt_names ionames[] ={ + { IPOPT_NOP, 0x000001, 1, "nop" }, /* RFC791 */ + { IPOPT_RR, 0x000002, 7, "rr" }, /* 1 route */ + { IPOPT_ZSU, 0x000004, 3, "zsu" }, /* size ?? */ + { IPOPT_MTUP, 0x000008, 3, "mtup" }, /* RFC1191 */ + { IPOPT_MTUR, 0x000010, 3, "mtur" }, /* RFC1191 */ + { IPOPT_ENCODE, 0x000020, 3, "encode" }, /* size ?? */ + { IPOPT_TS, 0x000040, 8, "ts" }, /* 1 TS */ + { IPOPT_TR, 0x000080, 3, "tr" }, /* RFC1393 */ + { IPOPT_SECURITY,0x000100, 11, "sec" }, /* RFC1108 */ + { IPOPT_SECURITY,0x000100, 11, "sec-class" }, /* RFC1108 */ + { IPOPT_LSRR, 0x000200, 7, "lsrr" }, /* 1 route */ + { IPOPT_E_SEC, 0x000400, 3, "e-sec" }, /* RFC1108 */ + { IPOPT_CIPSO, 0x000800, 3, "cipso" }, /* size ?? */ + { IPOPT_SATID, 0x001000, 4, "satid" }, /* RFC791 */ + { IPOPT_SSRR, 0x002000, 7, "ssrr" }, /* 1 route */ + { IPOPT_ADDEXT, 0x004000, 3, "addext" }, /* IPv7 ?? */ + { IPOPT_VISA, 0x008000, 3, "visa" }, /* size ?? */ + { IPOPT_IMITD, 0x010000, 3, "imitd" }, /* size ?? */ + { IPOPT_EIP, 0x020000, 3, "eip" }, /* RFC1385 */ + { IPOPT_FINN, 0x040000, 3, "finn" }, /* size ?? */ + { IPOPT_DPS, 0x080000, 3, "dps" }, /* size ?? */ + { IPOPT_SDB, 0x100000, 3, "sdb" }, /* size ?? */ + { IPOPT_NSAPA, 0x200000, 3, "nsapa" }, /* size ?? */ + { IPOPT_RTRALRT,0x400000, 3, "rtralrt" }, /* RFC2113 */ + { IPOPT_UMP, 0x800000, 3, "ump" }, /* size ?? */ + { 0, 0, 0, (char *)NULL } /* must be last */ +}; diff --git a/contrib/ipfilter/lib/ipf_dotuning.c b/contrib/ipfilter/lib/ipf_dotuning.c new file mode 100644 index 000000000000..c9416ff2411b --- /dev/null +++ b/contrib/ipfilter/lib/ipf_dotuning.c @@ -0,0 +1,60 @@ +/* $NetBSD$ */ + +#include "ipf.h" +#include "ipl.h" +#include + +void ipf_dotuning(fd, tuneargs, iocfn) +int fd; +char *tuneargs; +ioctlfunc_t iocfn; +{ + ipfobj_t obj; + ipftune_t tu; + char *s, *t; + + bzero((char *)&tu, sizeof(tu)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(tu);; + obj.ipfo_ptr = (void *)&tu; + obj.ipfo_type = IPFOBJ_TUNEABLE; + + for (s = strtok(tuneargs, ","); s != NULL; s = strtok(NULL, ",")) { + if (!strcmp(s, "list")) { + while (1) { + if ((*iocfn)(fd, SIOCIPFGETNEXT, &obj) == -1) { + perror("ioctl(SIOCIPFGETNEXT)"); + break; + } + if (tu.ipft_cookie == NULL) + break; + + tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; + printtunable(&tu); + } + } else if ((t = strchr(s, '=')) != NULL) { + *t++ = '\0'; + strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); + if (sscanf(t, "%lu", &tu.ipft_vlong) == 1) { + if ((*iocfn)(fd, SIOCIPFSET, &obj) == -1) { + perror("ioctl(SIOCIPFSET)"); + return; + } + } else { + fprintf(stderr, "invalid value '%s'\n", s); + return; + } + } else { + strncpy(tu.ipft_name, s, sizeof(tu.ipft_name)); + if ((*iocfn)(fd, SIOCIPFGET, &obj) == -1) { + perror("ioctl(SIOCIPFGET)"); + return; + } + if (tu.ipft_cookie == NULL) + return; + + tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; + printtunable(&tu); + } + } +} diff --git a/contrib/ipfilter/lib/ipft_ef.c b/contrib/ipfilter/lib/ipft_ef.c new file mode 100644 index 000000000000..eebc417fc8c8 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_ef.c @@ -0,0 +1,130 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_ef.c,v 1.14 2004/01/08 13:34:31 darrenr Exp + */ + +/* + icmp type + lnth proto source destination src port dst port + +etherfind -n + + 60 tcp 128.250.20.20 128.250.133.13 2419 telnet + +etherfind -n -t + + 0.32 91 04 131.170.1.10 128.250.133.13 + 0.33 566 udp 128.250.37.155 128.250.133.3 901 901 +*/ + +#include "ipf.h" +#include "ipt.h" + +#ifndef linux +#include +#endif +#include + + +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_ef.c,v 1.14 2004/01/08 13:34:31 darrenr Exp"; +#endif + +static int etherf_open __P((char *)); +static int etherf_close __P((void)); +static int etherf_readip __P((char *, int, char **, int *)); + +struct ipread etherf = { etherf_open, etherf_close, etherf_readip, 0 }; + +static FILE *efp = NULL; +static int efd = -1; + + +static int etherf_open(fname) +char *fname; +{ + if (efd != -1) + return efd; + + if (!strcmp(fname, "-")) { + efd = 0; + efp = stdin; + } else { + efd = open(fname, O_RDONLY); + efp = fdopen(efd, "r"); + } + return efd; +} + + +static int etherf_close() +{ + return close(efd); +} + + +static int etherf_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + struct tcpiphdr pkt; + ip_t *ip = (ip_t *)&pkt; + char src[16], dst[16], sprt[16], dprt[16]; + char lbuf[128], len[8], prot[8], time[8], *s; + int slen, extra = 0, i; + + if (!fgets(lbuf, sizeof(lbuf) - 1, efp)) + return 0; + + if ((s = strchr(lbuf, '\n'))) + *s = '\0'; + lbuf[sizeof(lbuf)-1] = '\0'; + + bzero(&pkt, sizeof(pkt)); + + if (sscanf(lbuf, "%7s %7s %15s %15s %15s %15s", len, prot, src, dst, + sprt, dprt) != 6) + if (sscanf(lbuf, "%7s %7s %7s %15s %15s %15s %15s", time, + len, prot, src, dst, sprt, dprt) != 7) + return -1; + + ip->ip_p = getproto(prot); + + switch (ip->ip_p) { + case IPPROTO_TCP : + case IPPROTO_UDP : + s = strtok(NULL, " :"); + ip->ip_len += atoi(s); + if (ip->ip_p == IPPROTO_TCP) + extra = sizeof(struct tcphdr); + else if (ip->ip_p == IPPROTO_UDP) + extra = sizeof(struct udphdr); + break; +#ifdef IGMP + case IPPROTO_IGMP : + extra = sizeof(struct igmp); + break; +#endif + case IPPROTO_ICMP : + extra = sizeof(struct icmp); + break; + default : + break; + } + + (void) inet_aton(src, &ip->ip_src); + (void) inet_aton(dst, &ip->ip_dst); + ip->ip_len = atoi(len); + IP_HL_A(ip, sizeof(ip_t)); + + slen = IP_HL(ip) + extra; + i = MIN(cnt, slen); + bcopy((char *)&pkt, buf, i); + return i; +} diff --git a/contrib/ipfilter/lib/ipft_hx.c b/contrib/ipfilter/lib/ipft_hx.c new file mode 100644 index 000000000000..3cc8ec5e908a --- /dev/null +++ b/contrib/ipfilter/lib/ipft_hx.c @@ -0,0 +1,158 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1995-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_hx.c,v 1.11.4.1 2004/12/09 19:41:20 darrenr Exp"; +#endif + +#include + +#include "ipf.h" +#include "ipt.h" + + +extern int opts; + +static int hex_open __P((char *)); +static int hex_close __P((void)); +static int hex_readip __P((char *, int, char **, int *)); +static char *readhex __P((char *, char *)); + +struct ipread iphex = { hex_open, hex_close, hex_readip, 0 }; +static FILE *tfp = NULL; +static int tfd = -1; + +static int hex_open(fname) +char *fname; +{ + if (tfp && tfd != -1) { + rewind(tfp); + return tfd; + } + + if (!strcmp(fname, "-")) { + tfd = 0; + tfp = stdin; + } else { + tfd = open(fname, O_RDONLY); + if (tfd != -1) + tfp = fdopen(tfd, "r"); + } + return tfd; +} + + +static int hex_close() +{ + int cfd = tfd; + + tfd = -1; + return close(cfd); +} + + +static int hex_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + register char *s, *t, *u; + char line[513]; + ip_t *ip; + + /* + * interpret start of line as possibly "[ifname]" or + * "[in/out,ifname]". + */ + if (ifn) + *ifn = NULL; + if (dir) + *dir = 0; + ip = (ip_t *)buf; + while (fgets(line, sizeof(line)-1, tfp)) { + if ((s = strchr(line, '\n'))) { + if (s == line) + return (char *)ip - buf; + *s = '\0'; + } + if ((s = strchr(line, '#'))) + *s = '\0'; + if (!*line) + continue; + if (!(opts & OPT_BRIEF)) { + printf("input: %s", line); + } + + if ((*line == '[') && (s = strchr(line, ']'))) { + t = line + 1; + if (s - t > 0) { + *s++ = '\0'; + if ((u = strchr(t, ',')) && (u < s)) { + u++; + if (ifn) + *ifn = strdup(u); + if (dir) { + if (*t == 'i') + *dir = 0; + else if (*t == 'o') + *dir = 1; + } + } else if (ifn) + *ifn = t; + } + } else + s = line; + t = (char *)ip; + ip = (ip_t *)readhex(s, (char *)ip); + if (!(opts & OPT_BRIEF)) { + if (opts & OPT_ASCII) { + if (t < (char *)ip) + putchar('\t'); + while (t < (char *)ip) { + if (ISPRINT(*t) && ISASCII(*t)) + putchar(*t); + else + putchar('.'); + t++; + } + } + putchar('\n'); + fflush(stdout); + } + } + return -1; +} + + +static char *readhex(src, dst) +register char *src, *dst; +{ + int state = 0; + char c; + + while ((c = *src++)) { + if (ISSPACE(c)) { + if (state) { + dst++; + state = 0; + } + continue; + } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')) { + c = ISDIGIT(c) ? (c - '0') : (TOUPPER(c) - 55); + if (state == 0) { + *dst = (c << 4); + state++; + } else { + *dst++ |= c; + state = 0; + } + } else + break; + } + return dst; +} diff --git a/contrib/ipfilter/lib/ipft_pc.c b/contrib/ipfilter/lib/ipft_pc.c new file mode 100644 index 000000000000..3678d7868c4c --- /dev/null +++ b/contrib/ipfilter/lib/ipft_pc.c @@ -0,0 +1,252 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_pc.c,v 1.10 2004/02/07 18:17:40 darrenr Exp + */ +#include "ipf.h" +#include "pcap-ipf.h" +#include "bpf-ipf.h" +#include "ipt.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ipft_pc.c,v 1.10 2004/02/07 18:17:40 darrenr Exp"; +#endif + +struct llc { + int lc_type; + int lc_sz; /* LLC header length */ + int lc_to; /* LLC Type offset */ + int lc_tl; /* LLC Type length */ +}; + +/* + * While many of these maybe the same, some do have different header formats + * which make this useful. + */ + +static struct llc llcs[] = { + { DLT_NULL, 0, 0, 0 }, + { DLT_EN10MB, 14, 12, 2 }, + { DLT_EN3MB, 0, 0, 0 }, + { DLT_AX25, 0, 0, 0 }, + { DLT_PRONET, 0, 0, 0 }, + { DLT_CHAOS, 0, 0, 0 }, + { DLT_IEEE802, 0, 0, 0 }, + { DLT_ARCNET, 0, 0, 0 }, + { DLT_SLIP, 0, 0, 0 }, + { DLT_PPP, 0, 0, 0 }, + { DLT_FDDI, 0, 0, 0 }, +#ifdef DLT_ATMRFC1483 + { DLT_ATMRFC1483, 0, 0, 0 }, +#endif + { DLT_RAW, 0, 0, 0 }, +#ifdef DLT_ENC + { DLT_ENC, 0, 0, 0 }, +#endif +#ifdef DLT_SLIP_BSDOS + { DLT_SLIP_BSDOS, 0, 0, 0 }, +#endif +#ifdef DLT_PPP_BSDOS + { DLT_PPP_BSDOS, 0, 0, 0 }, +#endif +#ifdef DLT_HIPPI + { DLT_HIPPI, 0, 0, 0 }, +#endif +#ifdef DLT_HDLC + { DLT_HDLC, 0, 0, 0 }, +#endif +#ifdef DLT_PPP_SERIAL + { DLT_PPP_SERIAL, 4, 4, 0 }, +#endif +#ifdef DLT_PPP_ETHER + { DLT_PPP_ETHER, 8, 8, 0 }, +#endif +#ifdef DLT_ECONET + { DLT_ECONET, 0, 0, 0 }, +#endif + { -1, -1, -1, -1 } +}; + +static int pcap_open __P((char *)); +static int pcap_close __P((void)); +static int pcap_readip __P((char *, int, char **, int *)); +static void swap_hdr __P((pcaphdr_t *)); +static int pcap_read_rec __P((struct pcap_pkthdr *)); + +static int pfd = -1, swapped = 0; +static struct llc *llcp = NULL; + +struct ipread pcap = { pcap_open, pcap_close, pcap_readip, 0 }; + +#define SWAPLONG(y) \ + ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) +#define SWAPSHORT(y) \ + ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) ) + +static void swap_hdr(p) +pcaphdr_t *p; +{ + p->pc_v_maj = SWAPSHORT(p->pc_v_maj); + p->pc_v_min = SWAPSHORT(p->pc_v_min); + p->pc_zone = SWAPLONG(p->pc_zone); + p->pc_sigfigs = SWAPLONG(p->pc_sigfigs); + p->pc_slen = SWAPLONG(p->pc_slen); + p->pc_type = SWAPLONG(p->pc_type); +} + +static int pcap_open(fname) +char *fname; +{ + pcaphdr_t ph; + int fd, i; + + if (pfd != -1) + return pfd; + + if (!strcmp(fname, "-")) + fd = 0; + else if ((fd = open(fname, O_RDONLY)) == -1) + return -1; + + if (read(fd, (char *)&ph, sizeof(ph)) != sizeof(ph)) + return -2; + + if (ph.pc_id != TCPDUMP_MAGIC) { + if (SWAPLONG(ph.pc_id) != TCPDUMP_MAGIC) { + (void) close(fd); + return -2; + } + swapped = 1; + swap_hdr(&ph); + } + + if (ph.pc_v_maj != PCAP_VERSION_MAJ) { + (void) close(fd); + return -2; + } + + for (i = 0; llcs[i].lc_type != -1; i++) + if (llcs[i].lc_type == ph.pc_type) { + llcp = llcs + i; + break; + } + + if (llcp == NULL) { + (void) close(fd); + return -2; + } + + pfd = fd; + printf("opened pcap file %s:\n", fname); + printf("\tid: %08x version: %d.%d type: %d snap %d\n", + ph.pc_id, ph.pc_v_maj, ph.pc_v_min, ph.pc_type, ph.pc_slen); + + return fd; +} + + +static int pcap_close() +{ + return close(pfd); +} + + +/* + * read in the header (and validate) which should be the first record + * in a pcap file. + */ +static int pcap_read_rec(rec) +struct pcap_pkthdr *rec; +{ + int n, p; + + if (read(pfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) + return -2; + + if (swapped) { + rec->ph_clen = SWAPLONG(rec->ph_clen); + rec->ph_len = SWAPLONG(rec->ph_len); + rec->ph_ts.tv_sec = SWAPLONG(rec->ph_ts.tv_sec); + rec->ph_ts.tv_usec = SWAPLONG(rec->ph_ts.tv_usec); + } + p = rec->ph_clen; + n = MIN(p, rec->ph_len); + if (!n || n < 0) + return -3; + + return p; +} + + +#ifdef notyet +/* + * read an entire pcap packet record. only the data part is copied into + * the available buffer, with the number of bytes copied returned. + */ +static int pcap_read(buf, cnt) +char *buf; +int cnt; +{ + struct pcap_pkthdr rec; + static char *bufp = NULL; + int i, n; + + if ((i = pcap_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + + if (read(pfd, bufp, i) != i) + return -2; + + n = MIN(i, cnt); + bcopy(bufp, buf, n); + return n; +} +#endif + + +/* + * return only an IP packet read into buf + */ +static int pcap_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + static char *bufp = NULL; + struct pcap_pkthdr rec; + struct llc *l; + char *s, ty[4]; + int i, n; + + l = llcp; + + /* do { */ + if ((i = pcap_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + s = bufp; + + if (read(pfd, s, i) != i) + return -2; + + i -= l->lc_sz; + s += l->lc_to; + bcopy(s, ty, l->lc_tl); + s += l->lc_tl; + /* } while (ty[0] != 0x8 && ty[1] != 0); */ + n = MIN(i, cnt); + bcopy(s, buf, n); + return n; +} diff --git a/contrib/ipfilter/lib/ipft_sn.c b/contrib/ipfilter/lib/ipft_sn.c new file mode 100644 index 000000000000..1458821e658e --- /dev/null +++ b/contrib/ipfilter/lib/ipft_sn.c @@ -0,0 +1,197 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_sn.c,v 1.7 2003/02/16 02:32:36 darrenr Exp + */ + +/* + * Written to comply with the recent RFC 1761 from Sun. + */ +#include "ipf.h" +#include "snoop.h" +#include "ipt.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ipft_sn.c,v 1.7 2003/02/16 02:32:36 darrenr Exp"; +#endif + +struct llc { + int lc_sz; /* LLC header length */ + int lc_to; /* LLC Type offset */ + int lc_tl; /* LLC Type length */ +}; + +/* + * While many of these maybe the same, some do have different header formats + * which make this useful. + */ +static struct llc llcs[SDL_MAX+1] = { + { 0, 0, 0 }, /* SDL_8023 */ + { 0, 0, 0 }, /* SDL_8024 */ + { 0, 0, 0 }, /* SDL_8025 */ + { 0, 0, 0 }, /* SDL_8026 */ + { 14, 12, 2 }, /* SDL_ETHER */ + { 0, 0, 0 }, /* SDL_HDLC */ + { 0, 0, 0 }, /* SDL_CHSYNC */ + { 0, 0, 0 }, /* SDL_IBMCC */ + { 0, 0, 0 }, /* SDL_FDDI */ + { 0, 0, 0 }, /* SDL_OTHER */ +}; + +static int snoop_open __P((char *)); +static int snoop_close __P((void)); +static int snoop_readip __P((char *, int, char **, int *)); + +static int sfd = -1, s_type = -1; +static int snoop_read_rec __P((struct snooppkt *)); + +struct ipread snoop = { snoop_open, snoop_close, snoop_readip, 0 }; + + +static int snoop_open(fname) +char *fname; +{ + struct snoophdr sh; + int fd; + int s_v; + + if (sfd != -1) + return sfd; + + if (!strcmp(fname, "-")) + fd = 0; + else if ((fd = open(fname, O_RDONLY)) == -1) + return -1; + + if (read(fd, (char *)&sh, sizeof(sh)) != sizeof(sh)) + return -2; + + s_v = (int)ntohl(sh.s_v); + s_type = (int)ntohl(sh.s_type); + + if (s_v != SNOOP_VERSION || + s_type < 0 || s_type > SDL_MAX) { + (void) close(fd); + return -2; + } + + sfd = fd; + printf("opened snoop file %s:\n", fname); + printf("\tid: %8.8s version: %d type: %d\n", sh.s_id, s_v, s_type); + + return fd; +} + + +static int snoop_close() +{ + return close(sfd); +} + + +/* + * read in the header (and validate) which should be the first record + * in a snoop file. + */ +static int snoop_read_rec(rec) +struct snooppkt *rec; +{ + int n, plen, ilen; + + if (read(sfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) + return -2; + + ilen = (int)ntohl(rec->sp_ilen); + plen = (int)ntohl(rec->sp_plen); + if (ilen > plen || plen < sizeof(*rec)) + return -2; + + plen -= sizeof(*rec); + n = MIN(plen, ilen); + if (!n || n < 0) + return -3; + + return plen; +} + + +#ifdef notyet +/* + * read an entire snoop packet record. only the data part is copied into + * the available buffer, with the number of bytes copied returned. + */ +static int snoop_read(buf, cnt) +char *buf; +int cnt; +{ + struct snooppkt rec; + static char *bufp = NULL; + int i, n; + + if ((i = snoop_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + + if (read(sfd, bufp, i) != i) + return -2; + + n = MIN(i, cnt); + bcopy(bufp, buf, n); + return n; +} +#endif + + +/* + * return only an IP packet read into buf + */ +static int snoop_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + static char *bufp = NULL; + struct snooppkt rec; + struct llc *l; + char ty[4], *s; + int i, n; + + do { + if ((i = snoop_read_rec(&rec)) <= 0) + return i; + + if (!bufp) + bufp = malloc(i); + else + bufp = realloc(bufp, i); + s = bufp; + + if (read(sfd, s, i) != i) + return -2; + + l = &llcs[s_type]; + i -= l->lc_to; + s += l->lc_to; + /* + * XXX - bogus assumption here on the part of the time field + * that it won't be greater than 4 bytes and the 1st two will + * have the values 8 and 0 for IP. Should be a table of + * these too somewhere. Really only works for SDL_ETHER. + */ + bcopy(s, ty, l->lc_tl); + } while (ty[0] != 0x8 && ty[1] != 0); + + i -= l->lc_tl; + s += l->lc_tl; + n = MIN(i, cnt); + bcopy(s, buf, n); + + return n; +} diff --git a/contrib/ipfilter/lib/ipft_td.c b/contrib/ipfilter/lib/ipft_td.c new file mode 100644 index 000000000000..b278c7293269 --- /dev/null +++ b/contrib/ipfilter/lib/ipft_td.c @@ -0,0 +1,174 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp + */ + +/* +tcpdump -n + +00:05:47.816843 128.231.76.76.3291 > 224.2.252.231.36573: udp 36 (encap) + +tcpdump -nq + +00:33:48.410771 192.73.213.11.1463 > 224.2.248.153.59360: udp 31 (encap) + +tcpdump -nqt + +128.250.133.13.23 > 128.250.20.20.2419: tcp 27 + +tcpdump -nqtt + +123456789.1234567 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 + +tcpdump -nqte + +8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 + +*/ + +#include "ipf.h" +#include "ipt.h" + +#ifndef linux +#include +#endif +#include + + +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp"; +#endif + +static int tcpd_open __P((char *)); +static int tcpd_close __P((void)); +static int tcpd_readip __P((char *, int, char **, int *)); +static int count_dots __P((char *)); + +struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip, 0 }; + +static FILE *tfp = NULL; +static int tfd = -1; + + +static int tcpd_open(fname) +char *fname; +{ + if (tfd != -1) + return tfd; + + if (!strcmp(fname, "-")) { + tfd = 0; + tfp = stdin; + } else { + tfd = open(fname, O_RDONLY); + tfp = fdopen(tfd, "r"); + } + return tfd; +} + + +static int tcpd_close() +{ + (void) fclose(tfp); + return close(tfd); +} + + +static int count_dots(str) +char *str; +{ + int i = 0; + + while (*str) + if (*str++ == '.') + i++; + return i; +} + + +static int tcpd_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + struct tcpiphdr pkt; + ip_t *ip = (ip_t *)&pkt; + char src[32], dst[32], misc[256], time[32], link1[32], link2[32]; + char lbuf[160], *s; + int n, slen, extra = 0; + + if (!fgets(lbuf, sizeof(lbuf) - 1, tfp)) + return 0; + + if ((s = strchr(lbuf, '\n'))) + *s = '\0'; + lbuf[sizeof(lbuf)-1] = '\0'; + + bzero(&pkt, sizeof(pkt)); + + if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3) + if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s", + time, src, dst, misc)) != 4) + if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s", + link1, link2, src, dst, misc)) != 5) { + n = sscanf(lbuf, + "%31s %31s %31s: %31s > %31s: %255s", + time, link1, link2, src, dst, misc); + if (n != 6) + return -1; + } + + if (count_dots(dst) == 4) { + s = strrchr(src, '.'); + *s++ = '\0'; + (void) inet_aton(src, &ip->ip_src); + pkt.ti_sport = htons(atoi(s)); + *--s = '.'; + s = strrchr(dst, '.'); + + *s++ = '\0'; + (void) inet_aton(src, &ip->ip_dst); + pkt.ti_dport = htons(atoi(s)); + *--s = '.'; + + } else { + (void) inet_aton(src, &ip->ip_src); + (void) inet_aton(src, &ip->ip_dst); + } + ip->ip_len = sizeof(ip_t); + IP_HL_A(ip, sizeof(ip_t)); + + s = strtok(misc, " :"); + ip->ip_p = getproto(s); + + switch (ip->ip_p) + { + case IPPROTO_TCP : + case IPPROTO_UDP : + s = strtok(NULL, " :"); + ip->ip_len += atoi(s); + if (ip->ip_p == IPPROTO_TCP) + extra = sizeof(struct tcphdr); + else if (ip->ip_p == IPPROTO_UDP) + extra = sizeof(struct udphdr); + break; +#ifdef IGMP + case IPPROTO_IGMP : + extra = sizeof(struct igmp); + break; +#endif + case IPPROTO_ICMP : + extra = sizeof(struct icmp); + break; + default : + break; + } + + slen = IP_HL(ip) + extra + ip->ip_len; + return slen; +} diff --git a/contrib/ipfilter/lib/ipft_tx.c b/contrib/ipfilter/lib/ipft_tx.c new file mode 100644 index 000000000000..c77fbc42277d --- /dev/null +++ b/contrib/ipfilter/lib/ipft_tx.c @@ -0,0 +1,331 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1995-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipft_tx.c,v 1.15.2.2 2004/12/09 19:41:21 darrenr Exp + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipft_tx.c,v 1.15.2.2 2004/12/09 19:41:21 darrenr Exp"; +#endif + +#include + +#include "ipf.h" +#include "ipt.h" + +#ifndef linux +#include +#endif +#include + + +extern int opts; + +static char *tx_proto = ""; + +static int text_open __P((char *)), text_close __P((void)); +static int text_readip __P((char *, int, char **, int *)); +static int parseline __P((char *, ip_t *, char **, int *)); + +static char _tcp_flagset[] = "FSRPAUEC"; +static u_char _tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, + TH_ACK, TH_URG, TH_ECN, TH_CWR }; + +struct ipread iptext = { text_open, text_close, text_readip, R_DO_CKSUM }; +static FILE *tfp = NULL; +static int tfd = -1; + +static u_32_t tx_hostnum __P((char *, int *)); +static u_short tx_portnum __P((char *)); + + +/* + * returns an ip address as a long var as a result of either a DNS lookup or + * straight inet_addr() call + */ +static u_32_t tx_hostnum(host, resolved) +char *host; +int *resolved; +{ + u_32_t ipa; + + *resolved = 0; + if (!strcasecmp("any", host)) + return 0L; + if (ISDIGIT(*host)) + return inet_addr(host); + + if (gethost(host, &ipa) == -1) { + *resolved = -1; + fprintf(stderr, "can't resolve hostname: %s\n", host); + return 0; + } + return ipa; +} + + +/* + * find the port number given by the name, either from getservbyname() or + * straight atoi() + */ +static u_short tx_portnum(name) +char *name; +{ + struct servent *sp, *sp2; + u_short p1 = 0; + + if (ISDIGIT(*name)) + return (u_short)atoi(name); + if (!tx_proto) + tx_proto = "tcp/udp"; + if (strcasecmp(tx_proto, "tcp/udp")) { + sp = getservbyname(name, tx_proto); + if (sp) + return ntohs(sp->s_port); + (void) fprintf(stderr, "unknown service \"%s\".\n", name); + return 0; + } + sp = getservbyname(name, "tcp"); + if (sp) + p1 = sp->s_port; + sp2 = getservbyname(name, "udp"); + if (!sp || !sp2) { + (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n", + name); + return 0; + } + if (p1 != sp2->s_port) { + (void) fprintf(stderr, "%s %d/tcp is a different port to ", + name, p1); + (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port); + return 0; + } + return ntohs(p1); +} + + +char *tx_icmptypes[] = { + "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", + "redir", (char *)NULL, (char *)NULL, "echo", "routerad", + "routersol", "timex", "paramprob", "timest", "timestrep", + "inforeq", "inforep", "maskreq", "maskrep", "END" +}; + +static int text_open(fname) +char *fname; +{ + if (tfp && tfd != -1) { + rewind(tfp); + return tfd; + } + + if (!strcmp(fname, "-")) { + tfd = 0; + tfp = stdin; + } else { + tfd = open(fname, O_RDONLY); + if (tfd != -1) + tfp = fdopen(tfd, "r"); + } + return tfd; +} + + +static int text_close() +{ + int cfd = tfd; + + tfd = -1; + return close(cfd); +} + + +static int text_readip(buf, cnt, ifn, dir) +char *buf, **ifn; +int cnt, *dir; +{ + register char *s; + char line[513]; + + *ifn = NULL; + while (fgets(line, sizeof(line)-1, tfp)) { + if ((s = strchr(line, '\n'))) + *s = '\0'; + if ((s = strchr(line, '\r'))) + *s = '\0'; + if ((s = strchr(line, '#'))) + *s = '\0'; + if (!*line) + continue; + if (!(opts & OPT_BRIEF)) + printf("input: %s\n", line); + *ifn = NULL; + *dir = 0; + if (!parseline(line, (ip_t *)buf, ifn, dir)) +#if 0 + return sizeof(ip_t) + sizeof(tcphdr_t); +#else + return sizeof(ip_t); +#endif + } + return -1; +} + +static int parseline(line, ip, ifn, out) +char *line; +ip_t *ip; +char **ifn; +int *out; +{ + tcphdr_t th, *tcp = &th; + struct icmp icmp, *ic = &icmp; + char *cps[20], **cpp, c, ipopts[68]; + int i, r; + + if (*ifn) + free(*ifn); + bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip)); + bzero((char *)tcp, sizeof(*tcp)); + bzero((char *)ic, sizeof(*ic)); + bzero(ipopts, sizeof(ipopts)); + IP_HL_A(ip, sizeof(*ip) >> 2); + IP_V_A(ip, IPVERSION); + for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; ) + cps[++i] = strtok(NULL, " \b\t\r\n"); + + cpp = cps; + if (!*cpp) + return 1; + + c = **cpp; + if (!ISALPHA(c) || (TOLOWER(c) != 'o' && TOLOWER(c) != 'i')) { + fprintf(stderr, "bad direction \"%s\"\n", *cpp); + return 1; + } + *out = (TOLOWER(c) == 'o') ? 1 : 0; + cpp++; + if (!*cpp) + return 1; + + if (!strcasecmp(*cpp, "on")) { + cpp++; + if (!*cpp) + return 1; + *ifn = strdup(*cpp++); + if (!*cpp) + return 1; + } + + c = **cpp; + ip->ip_len = sizeof(ip_t); + if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") || + !strcasecmp(*cpp, "icmp")) { + if (c == 't') { + ip->ip_p = IPPROTO_TCP; + ip->ip_len += sizeof(struct tcphdr); + tx_proto = "tcp"; + } else if (c == 'u') { + ip->ip_p = IPPROTO_UDP; + ip->ip_len += sizeof(struct udphdr); + tx_proto = "udp"; + } else { + ip->ip_p = IPPROTO_ICMP; + ip->ip_len += ICMPERR_IPICMPHLEN; + tx_proto = "icmp"; + } + cpp++; + } else if (ISDIGIT(**cpp) && !index(*cpp, '.')) { + ip->ip_p = atoi(*cpp); + cpp++; + } else + ip->ip_p = IPPROTO_IP; + + if (!*cpp) + return 1; + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { + char *last; + + last = strchr(*cpp, ','); + if (!last) { + fprintf(stderr, "tcp/udp with no source port\n"); + return 1; + } + *last++ = '\0'; + tcp->th_sport = htons(tx_portnum(last)); + if (ip->ip_p == IPPROTO_TCP) { + tcp->th_win = htons(4096); + TCP_OFF_A(tcp, sizeof(*tcp) >> 2); + } + } + ip->ip_src.s_addr = tx_hostnum(*cpp, &r); + cpp++; + if (!*cpp) + return 1; + + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { + char *last; + + last = strchr(*cpp, ','); + if (!last) { + fprintf(stderr, "tcp/udp with no destination port\n"); + return 1; + } + *last++ = '\0'; + tcp->th_dport = htons(tx_portnum(last)); + } + ip->ip_dst.s_addr = tx_hostnum(*cpp, &r); + cpp++; + if (*cpp && ip->ip_p == IPPROTO_TCP) { + extern char _tcp_flagset[]; + extern u_char _tcp_flags[]; + char *s, *t; + + tcp->th_flags = 0; + for (s = *cpp; *s; s++) + if ((t = strchr(_tcp_flagset, *s))) + tcp->th_flags |= _tcp_flags[t - _tcp_flagset]; + if (tcp->th_flags) + cpp++; + if (tcp->th_flags == 0) + abort(); + if (tcp->th_flags & TH_URG) + tcp->th_urp = htons(1); + } else if (*cpp && ip->ip_p == IPPROTO_ICMP) { + extern char *tx_icmptypes[]; + char **s, *t; + int i; + + for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END"); + s++, i++) + if (*s && !strncasecmp(*cpp, *s, strlen(*s))) { + ic->icmp_type = i; + if ((t = strchr(*cpp, ','))) + ic->icmp_code = atoi(t+1); + cpp++; + break; + } + } + + if (*cpp && !strcasecmp(*cpp, "opt")) { + u_long olen; + + cpp++; + olen = buildopts(*cpp, ipopts, (IP_HL(ip) - 5) << 2); + if (olen) { + bcopy(ipopts, (char *)(ip + 1), olen); + IP_HL_A(ip, IP_HL(ip) + (olen >> 2)); + } + } + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) + bcopy((char *)tcp, ((char *)ip) + (IP_HL(ip) << 2), + sizeof(*tcp)); + else if (ip->ip_p == IPPROTO_ICMP) + bcopy((char *)ic, ((char *)ip) + (IP_HL(ip) << 2), + sizeof(*ic)); + ip->ip_len = htons(ip->ip_len); + return 0; +} diff --git a/contrib/ipfilter/lib/ipoptsec.c b/contrib/ipfilter/lib/ipoptsec.c new file mode 100644 index 000000000000..95bde9c04d9b --- /dev/null +++ b/contrib/ipfilter/lib/ipoptsec.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ipoptsec.c,v 1.2 2002/01/28 06:50:46 darrenr Exp + */ + +#include "ipf.h" + + +struct ipopt_names secclass[] = { + { IPSO_CLASS_RES4, 0x01, 0, "reserv-4" }, + { IPSO_CLASS_TOPS, 0x02, 0, "topsecret" }, + { IPSO_CLASS_SECR, 0x04, 0, "secret" }, + { IPSO_CLASS_RES3, 0x08, 0, "reserv-3" }, + { IPSO_CLASS_CONF, 0x10, 0, "confid" }, + { IPSO_CLASS_UNCL, 0x20, 0, "unclass" }, + { IPSO_CLASS_RES2, 0x40, 0, "reserv-2" }, + { IPSO_CLASS_RES1, 0x80, 0, "reserv-1" }, + { 0, 0, 0, NULL } /* must be last */ +}; + + +u_char seclevel(slevel) +char *slevel; +{ + struct ipopt_names *so; + + for (so = secclass; so->on_name; so++) + if (!strcasecmp(slevel, so->on_name)) + break; + + if (!so->on_name) { + fprintf(stderr, "no such security level: %s\n", slevel); + return 0; + } + return (u_char)so->on_value; +} + + +u_char secbit(class) +int class; +{ + struct ipopt_names *so; + + for (so = secclass; so->on_name; so++) + if (so->on_value == class) + break; + + if (!so->on_name) { + fprintf(stderr, "no such security class: %d\n", class); + return 0; + } + return (u_char)so->on_bit; +} diff --git a/contrib/ipfilter/lib/kmem.c b/contrib/ipfilter/lib/kmem.c new file mode 100644 index 000000000000..3f044bb20c5b --- /dev/null +++ b/contrib/ipfilter/lib/kmem.c @@ -0,0 +1,203 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * kmemcpy() - copies n bytes from kernel memory into user buffer. + * returns 0 on success, -1 on error. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#if defined(linux) || defined(__osf__) || defined(__sgi) || defined(__hpux) +# include +#endif + +#include "kmem.h" + +#ifndef __STDC__ +# define const +#endif + +#if !defined(lint) +static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; +static const char rcsid[] = "@(#)Id: kmem.c,v 1.16.2.1 2004/06/20 10:25:58 darrenr Exp"; +#endif + + + +#if !defined(__sgi) && !defined(__hpux) && !defined(__osf__) && !defined(linux) +/* + * For all platforms where there is a libkvm and a kvm_t, we use that... + */ +static kvm_t *kvm_f = NULL; + +#else +/* + *...and for the others (HP-UX, IRIX, Tru64), we have to provide our own. + */ + +typedef int * kvm_t; + +static kvm_t kvm_f = NULL; +static char *kvm_errstr = NULL; + +kvm_t kvm_open __P((char *, char *, char *, int, char *)); +int kvm_read __P((kvm_t, u_long, char *, size_t)); + +kvm_t kvm_open(kernel, core, swap, mode, errstr) +char *kernel, *core, *swap; +int mode; +char *errstr; +{ + kvm_t k; + int fd; + + kvm_errstr = errstr; + + if (core == NULL) + core = "/dev/kmem"; + + fd = open(core, mode); + if (fd == -1) + return NULL; + k = malloc(sizeof(*k)); + if (k == NULL) + return NULL; + *k = fd; + return k; +} + +int kvm_read(kvm, pos, buffer, size) +kvm_t kvm; +u_long pos; +char *buffer; +size_t size; +{ + int r = 0, left; + char *bufp; + + if (lseek(*kvm, pos, 0) == -1) { + if (kvm_errstr != NULL) { + fprintf(stderr, "%s", kvm_errstr); + perror("lseek"); + } + return -1; + } + + for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { + r = read(*kvm, bufp, left); +#ifdef __osf__ + /* + * Tru64 returns "0" for successful operation, not the number + * of bytes read. + */ + if (r == 0) + r = left; +#endif + if (r <= 0) + return -1; + } + return r; +} +#endif /* !defined(__sgi) && !defined(__hpux) && !defined(__osf__) */ + +int openkmem(kern, core) +char *kern, *core; +{ + kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); + if (kvm_f == NULL) + { + perror("openkmem:open"); + return -1; + } + return kvm_f != NULL; +} + +int kmemcpy(buf, pos, n) +register char *buf; +long pos; +register int n; +{ + register int r; + + if (!n) + return 0; + + if (kvm_f == NULL) + if (openkmem(NULL, NULL) == -1) + return -1; + + while ((r = kvm_read(kvm_f, pos, buf, n)) < n) + if (r <= 0) + { + fprintf(stderr, "pos=0x%lx ", (u_long)pos); + perror("kmemcpy:read"); + return -1; + } + else + { + buf += r; + pos += r; + n -= r; + } + return 0; +} + +int kstrncpy(buf, pos, n) +register char *buf; +long pos; +register int n; +{ + register int r; + + if (!n) + return 0; + + if (kvm_f == NULL) + if (openkmem(NULL, NULL) == -1) + return -1; + + while (n > 0) + { + r = kvm_read(kvm_f, pos, buf, 1); + if (r <= 0) + { + fprintf(stderr, "pos=0x%lx ", (u_long)pos); + perror("kmemcpy:read"); + return -1; + } + else + { + if (*buf == '\0') + break; + buf++; + pos++; + n--; + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/kmem.h b/contrib/ipfilter/lib/kmem.h new file mode 100644 index 000000000000..07a14f58b9ce --- /dev/null +++ b/contrib/ipfilter/lib/kmem.h @@ -0,0 +1,34 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * Id: kmem.h,v 1.2 2002/08/21 22:57:36 darrenr Exp + */ + +#ifndef __KMEM_H__ +#define __KMEM_H__ + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif +extern int openkmem __P((char *, char *)); +extern int kmemcpy __P((char *, long, int)); +extern int kstrncpy __P((char *, long, int)); + +#if defined(__NetBSD__) || defined(__OpenBSD) +# include +#endif + +#ifdef _PATH_KMEM +# define KMEM _PATH_KMEM +#else +# define KMEM "/dev/kmem" +#endif + +#endif /* __KMEM_H__ */ diff --git a/contrib/ipfilter/lib/kmemcpywrap.c b/contrib/ipfilter/lib/kmemcpywrap.c new file mode 100644 index 000000000000..274bcb1ab14a --- /dev/null +++ b/contrib/ipfilter/lib/kmemcpywrap.c @@ -0,0 +1,15 @@ +/* $NetBSD$ */ + +#include "ipf.h" +#include "kmem.h" + +int kmemcpywrap(from, to, size) +void *from, *to; +size_t size; +{ + int ret; + + ret = kmemcpy((caddr_t)to, (u_long)from, size); + return ret; +} + diff --git a/contrib/ipfilter/lib/kvatoname.c b/contrib/ipfilter/lib/kvatoname.c new file mode 100644 index 000000000000..030c63363377 --- /dev/null +++ b/contrib/ipfilter/lib/kvatoname.c @@ -0,0 +1,31 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#include +#include + +char *kvatoname(func, iocfunc) +ipfunc_t func; +ioctlfunc_t iocfunc; +{ + static char funcname[40]; + ipfunc_resolve_t res; + int fd; + + res.ipfu_addr = func; + res.ipfu_name[0] = '\0'; + fd = -1; + + if ((opts & OPT_DONOTHING) == 0) { + fd = open(IPL_NAME, O_RDONLY); + if (fd == -1) + return NULL; + } + (void) (*iocfunc)(fd, SIOCFUNCL, &res); + if (fd >= 0) + close(fd); + strncpy(funcname, res.ipfu_name, sizeof(funcname)); + funcname[sizeof(funcname) - 1] = '\0'; + return funcname; +} diff --git a/contrib/ipfilter/lib/load_hash.c b/contrib/ipfilter/lib/load_hash.c new file mode 100644 index 000000000000..4fc042bb4d2a --- /dev/null +++ b/contrib/ipfilter/lib/load_hash.c @@ -0,0 +1,112 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_hash.c,v 1.11.2.2 2005/02/01 02:44:05 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int load_hash(iphp, list, iocfunc) +iphtable_t *iphp; +iphtent_t *list; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtable_t iph; + iphtent_t *a; + size_t size; + int n; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + for (n = 0, a = list; a != NULL; a = a->ipe_next) + n++; + + op.iplo_arg = 0; + op.iplo_type = IPLT_HASH; + op.iplo_unit = iphp->iph_unit; + strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); + if (*op.iplo_name == '\0') + op.iplo_arg = IPHASH_ANON; + op.iplo_size = sizeof(iph); + op.iplo_struct = &iph; + iph.iph_unit = iphp->iph_unit; + iph.iph_type = iphp->iph_type; + strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); + iph.iph_flags = iphp->iph_flags; + if (n <= 0) + n = 1; + if (iphp->iph_size == 0) + size = n * 2 - 1; + else + size = iphp->iph_size; + if ((list == NULL) && (size == 1)) { + fprintf(stderr, + "WARNING: empty hash table %s, recommend setting %s\n", + iphp->iph_name, "size to match expected use"); + } + iph.iph_size = size; + iph.iph_seed = iphp->iph_seed; + iph.iph_table = NULL; + iph.iph_ref = 0; + + if ((opts & OPT_REMOVE) == 0) { + if ((*iocfunc)(hashfd, SIOCLOOKUPADDTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_hash:SIOCLOOKUPADDTABLE"); + return -1; + } + } + + strncpy(op.iplo_name, iph.iph_name, sizeof(op.iplo_name)); + strncpy(iphp->iph_name, iph.iph_name, sizeof(op.iplo_name)); + + if (opts & OPT_VERBOSE) { + for (a = list; a != NULL; a = a->ipe_next) { + a->ipe_addr.in4_addr = ntohl(a->ipe_addr.in4_addr); + a->ipe_mask.in4_addr = ntohl(a->ipe_mask.in4_addr); + } + iph.iph_table = calloc(size, sizeof(*iph.iph_table)); + if (iph.iph_table == NULL) { + perror("calloc(size, sizeof(*iph.iph_table))"); + return -1; + } + iph.iph_table[0] = list; + printhash(&iph, bcopywrap, iph.iph_name, opts); + free(iph.iph_table); + + for (a = list; a != NULL; a = a->ipe_next) { + a->ipe_addr.in4_addr = htonl(a->ipe_addr.in4_addr); + a->ipe_mask.in4_addr = htonl(a->ipe_mask.in4_addr); + } + } + + if (opts & OPT_DEBUG) + printf("Hash %s:\n", iph.iph_name); + + for (a = list; a != NULL; a = a->ipe_next) + load_hashnode(iphp->iph_unit, iph.iph_name, a, iocfunc); + + if ((opts & OPT_REMOVE) != 0) { + if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_hash:SIOCLOOKUPDELTABLE"); + return -1; + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_hashnode.c b/contrib/ipfilter/lib/load_hashnode.c new file mode 100644 index 000000000000..186ba05e8707 --- /dev/null +++ b/contrib/ipfilter/lib/load_hashnode.c @@ -0,0 +1,61 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_hashnode.c,v 1.2.4.1 2004/03/06 14:33:28 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int load_hashnode(unit, name, node, iocfunc) +int unit; +char *name; +iphtent_t *node; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtent_t ipe; + int err; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_HASH; + op.iplo_unit = unit; + op.iplo_arg = 0; + op.iplo_size = sizeof(ipe); + op.iplo_struct = &ipe; + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + bzero((char *)&ipe, sizeof(ipe)); + bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, + sizeof(ipe.ipe_addr)); + bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, + sizeof(ipe.ipe_mask)); + bcopy((char *)&node->ipe_group, (char *)&ipe.ipe_group, + sizeof(ipe.ipe_group)); + + if ((opts & OPT_REMOVE) == 0) + err = (*iocfunc)(hashfd, SIOCLOOKUPADDNODE, &op); + else + err = (*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op); + + if (err != 0) + if (!(opts & OPT_DONOTHING)) { + perror("load_hash:SIOCLOOKUP*NODE"); + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_pool.c b/contrib/ipfilter/lib/load_pool.c new file mode 100644 index 000000000000..5fab31151997 --- /dev/null +++ b/contrib/ipfilter/lib/load_pool.c @@ -0,0 +1,69 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_pool.c,v 1.14.2.2 2005/02/01 02:44:06 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int load_pool(plp, iocfunc) +ip_pool_t *plp; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + ip_pool_node_t *a; + ip_pool_t pool; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_unit = plp->ipo_unit; + op.iplo_type = IPLT_POOL; + op.iplo_arg = 0; + strncpy(op.iplo_name, plp->ipo_name, sizeof(op.iplo_name)); + op.iplo_size = sizeof(pool); + op.iplo_struct = &pool; + bzero((char *)&pool, sizeof(pool)); + strncpy(pool.ipo_name, plp->ipo_name, sizeof(pool.ipo_name)); + if (*plp->ipo_name == '\0') + op.iplo_arg |= IPOOL_ANON; + + if ((opts & OPT_REMOVE) == 0) { + if ((*iocfunc)(poolfd, SIOCLOOKUPADDTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_pool:SIOCLOOKUPADDTABLE"); + return -1; + } + } + + if ((opts & OPT_VERBOSE) != 0) { + pool.ipo_list = plp->ipo_list; + printpool(&pool, bcopywrap, pool.ipo_name, opts); + pool.ipo_list = NULL; + } + + for (a = plp->ipo_list; a != NULL; a = a->ipn_next) + load_poolnode(plp->ipo_unit, plp->ipo_name, a, iocfunc); + + if ((opts & OPT_REMOVE) != 0) { + if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("load_pool:SIOCLOOKUPDELTABLE"); + return -1; + } + } + return 0; +} diff --git a/contrib/ipfilter/lib/load_poolnode.c b/contrib/ipfilter/lib/load_poolnode.c new file mode 100644 index 000000000000..e9d233f18127 --- /dev/null +++ b/contrib/ipfilter/lib/load_poolnode.c @@ -0,0 +1,63 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: load_poolnode.c,v 1.3.2.1 2004/03/06 14:33:29 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int load_poolnode(role, name, node, iocfunc) +int role; +char *name; +ip_pool_node_t *node; +ioctlfunc_t iocfunc; +{ + ip_pool_node_t pn; + iplookupop_t op; + int err; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_unit = role; + op.iplo_type = IPLT_POOL; + op.iplo_arg = 0; + op.iplo_struct = &pn; + op.iplo_size = sizeof(pn); + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + bzero((char *)&pn, sizeof(pn)); + bcopy((char *)&node->ipn_addr, (char *)&pn.ipn_addr, + sizeof(pn.ipn_addr)); + bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, + sizeof(pn.ipn_mask)); + pn.ipn_info = node->ipn_info; + strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); + + if ((opts & OPT_REMOVE) == 0) + err = (*iocfunc)(poolfd, SIOCLOOKUPADDNODE, &op); + else + err = (*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op); + + if (err != 0) { + if ((opts & OPT_DONOTHING) == 0) { + perror("load_pool:SIOCLOOKUP*NODE"); + return -1; + } + } + + return 0; +} diff --git a/contrib/ipfilter/lib/loglevel.c b/contrib/ipfilter/lib/loglevel.c new file mode 100644 index 000000000000..31b4f17f81cf --- /dev/null +++ b/contrib/ipfilter/lib/loglevel.c @@ -0,0 +1,55 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: loglevel.c,v 1.5 2001/06/09 17:09:24 darrenr Exp + */ + +#include "ipf.h" + + +int loglevel(cpp, facpri, linenum) +char **cpp; +u_int *facpri; +int linenum; +{ + int fac, pri; + char *s; + + fac = 0; + pri = 0; + if (!*++cpp) { + fprintf(stderr, "%d: %s\n", linenum, + "missing identifier after level"); + return -1; + } + + s = strchr(*cpp, '.'); + if (s) { + *s++ = '\0'; + fac = fac_findname(*cpp); + if (fac == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown facility", *cpp); + return -1; + } + pri = pri_findname(s); + if (pri == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown priority", s); + return -1; + } + } else { + pri = pri_findname(*cpp); + if (pri == -1) { + fprintf(stderr, "%d: %s %s\n", linenum, + "Unknown priority", *cpp); + return -1; + } + } + *facpri = fac|pri; + return 0; +} diff --git a/contrib/ipfilter/lib/make_range.c b/contrib/ipfilter/lib/make_range.c new file mode 100644 index 000000000000..9ec3ca34e907 --- /dev/null +++ b/contrib/ipfilter/lib/make_range.c @@ -0,0 +1,26 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: make_range.c,v 1.2 2002/05/18 07:27:52 darrenr Exp + */ +#include "ipf.h" + + +alist_t *make_range(not, a1, a2) +int not; +struct in_addr a1, a2; +{ + alist_t *a; + + a = (alist_t *)calloc(1, sizeof(*a)); + if (a != NULL) { + a->al_1 = a1.s_addr; + a->al_2 = a2.s_addr; + a->al_not = not; + } + return a; +} diff --git a/contrib/ipfilter/lib/mutex_emul.c b/contrib/ipfilter/lib/mutex_emul.c new file mode 100644 index 000000000000..43b7f763afd0 --- /dev/null +++ b/contrib/ipfilter/lib/mutex_emul.c @@ -0,0 +1,80 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#define EMM_MAGIC 0x9d7adba3 + +void eMmutex_enter(mtx, file, line) +eMmutex_t *mtx; +char *file; +int line; +{ + if (mtx->eMm_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMmutex_enter(%p): bad magic: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + if (mtx->eMm_held != 0) { + fprintf(stderr, "%s:eMmutex_enter(%p): already locked: %d\n", + mtx->eMm_owner, mtx, mtx->eMm_held); + abort(); + } + mtx->eMm_held++; + mtx->eMm_heldin = file; + mtx->eMm_heldat = line; +} + + +void eMmutex_exit(mtx) +eMmutex_t *mtx; +{ + if (mtx->eMm_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMmutex_exit(%p): bad magic: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + if (mtx->eMm_held != 1) { + fprintf(stderr, "%s:eMmutex_exit(%p): not locked: %d\n", + mtx->eMm_owner, mtx, mtx->eMm_held); + abort(); + } + mtx->eMm_held--; + mtx->eMm_heldin = NULL; + mtx->eMm_heldat = 0; +} + + +void eMmutex_init(mtx, who) +eMmutex_t *mtx; +char *who; +{ + if (mtx->eMm_magic == EMM_MAGIC) { /* safe bet ? */ + fprintf(stderr, + "%s:eMmutex_init(%p): already initialised?: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + mtx->eMm_magic = EMM_MAGIC; + mtx->eMm_held = 0; + if (who != NULL) + mtx->eMm_owner = strdup(who); + else + mtx->eMm_owner = NULL; +} + + +void eMmutex_destroy(mtx) +eMmutex_t *mtx; +{ + if (mtx->eMm_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMmutex_destroy(%p): bad magic: %#x\n", + mtx->eMm_owner, mtx, mtx->eMm_magic); + abort(); + } + if (mtx->eMm_held != 0) { + fprintf(stderr, "%s:eMmutex_enter(%p): still locked: %d\n", + mtx->eMm_owner, mtx, mtx->eMm_held); + abort(); + } + memset(mtx, 0xa5, sizeof(*mtx)); +} diff --git a/contrib/ipfilter/lib/nametokva.c b/contrib/ipfilter/lib/nametokva.c new file mode 100644 index 000000000000..50f30775e3bf --- /dev/null +++ b/contrib/ipfilter/lib/nametokva.c @@ -0,0 +1,30 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#include +#include + +ipfunc_t nametokva(name, iocfunc) +char *name; +ioctlfunc_t iocfunc; +{ + ipfunc_resolve_t res; + int fd; + + strncpy(res.ipfu_name, name, sizeof(res.ipfu_name)); + res.ipfu_addr = NULL; + fd = -1; + + if ((opts & OPT_DONOTHING) == 0) { + fd = open(IPL_NAME, O_RDONLY); + if (fd == -1) + return NULL; + } + (void) (*iocfunc)(fd, SIOCFUNCL, &res); + if (fd >= 0) + close(fd); + if (res.ipfu_addr == NULL) + res.ipfu_addr = (ipfunc_t)-1; + return res.ipfu_addr; +} diff --git a/contrib/ipfilter/lib/nat_setgroupmap.c b/contrib/ipfilter/lib/nat_setgroupmap.c new file mode 100644 index 000000000000..ce64abb4dbb6 --- /dev/null +++ b/contrib/ipfilter/lib/nat_setgroupmap.c @@ -0,0 +1,34 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char rcsid[] = "@(#)Id: nat_setgroupmap.c,v 1.1 2003/04/13 06:40:14 darrenr Exp"; +#endif + +#include "ipf.h" + +void nat_setgroupmap(n) +ipnat_t *n; +{ + if (n->in_outmsk == n->in_inmsk) + n->in_ippip = 1; + else if (n->in_flags & IPN_AUTOPORTMAP) { + n->in_ippip = ~ntohl(n->in_inmsk); + if (n->in_outmsk != 0xffffffff) + n->in_ippip /= (~ntohl(n->in_outmsk) + 1); + n->in_ippip++; + if (n->in_ippip == 0) + n->in_ippip = 1; + n->in_ppip = USABLE_PORTS / n->in_ippip; + } else { + n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); + n->in_nip = 0; + if (!(n->in_ppip = n->in_pmin)) + n->in_ppip = 1; + n->in_ippip = USABLE_PORTS / n->in_ppip; + } +} diff --git a/contrib/ipfilter/lib/natparse.c b/contrib/ipfilter/lib/natparse.c new file mode 100644 index 000000000000..adbbeb9e7b31 --- /dev/null +++ b/contrib/ipfilter/lib/natparse.c @@ -0,0 +1,730 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; +static const char rcsid[] = "@(#)Id: natparse.c,v 1.8.2.1 2004/12/09 19:41:21 darrenr Exp"; +#endif + +#include +#include +#include + +#include "ipf.h" +#include "opts.h" + + +void nat_setgroupmap(n) +ipnat_t *n; +{ + if (n->in_outmsk == n->in_inmsk) + n->in_ippip = 1; + else if (n->in_flags & IPN_AUTOPORTMAP) { + n->in_ippip = ~ntohl(n->in_inmsk); + if (n->in_outmsk != 0xffffffff) + n->in_ippip /= (~ntohl(n->in_outmsk) + 1); + n->in_ippip++; + if (n->in_ippip == 0) + n->in_ippip = 1; + n->in_ppip = USABLE_PORTS / n->in_ippip; + } else { + n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); + n->in_nip = 0; + if (!(n->in_ppip = n->in_pmin)) + n->in_ppip = 1; + n->in_ippip = USABLE_PORTS / n->in_ppip; + } +} + + + +ipnat_t *natparse(line, linenum) +char *line; +int linenum; +{ + static ipnat_t ipn; + struct protoent *pr; + char *dnetm = NULL, *dport = NULL, *proto = NULL; + char *s, *t, *cps[31], **cpp; + int i, cnt; + + + if ((s = strchr(line, '\n'))) + *s = '\0'; + if ((s = strchr(line, '#'))) + *s = '\0'; + while (*line && ISSPACE(*line)) + line++; + if (!*line) + return NULL; + + bzero((char *)&ipn, sizeof(ipn)); + cnt = 0; + + for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) + cps[++i] = strtok(NULL, " \b\t\r\n"); + + cps[i] = NULL; + + if (cnt < 3) { + fprintf(stderr, "%d: not enough segments in line\n", linenum); + return NULL; + } + + cpp = cps; + + if (!strcasecmp(*cpp, "map")) + ipn.in_redir = NAT_MAP; + else if (!strcasecmp(*cpp, "map-block")) + ipn.in_redir = NAT_MAPBLK; + else if (!strcasecmp(*cpp, "rdr")) + ipn.in_redir = NAT_REDIRECT; + else if (!strcasecmp(*cpp, "bimap")) + ipn.in_redir = NAT_BIMAP; + else { + fprintf(stderr, "%d: unknown mapping: \"%s\"\n", + linenum, *cpp); + return NULL; + } + + cpp++; + + strncpy(ipn.in_ifnames[0], *cpp, sizeof(ipn.in_ifnames[0]) - 1); + ipn.in_ifnames[0][sizeof(ipn.in_ifnames[0]) - 1] = '\0'; + cpp++; + + if (!strcasecmp(*cpp, "from") || (**cpp == '!')) { + if (!strcmp(*cpp, "!")) { + cpp++; + if (strcasecmp(*cpp, "from")) { + fprintf(stderr, "Missing from after !\n"); + return NULL; + } + ipn.in_flags |= IPN_NOTSRC; + } else if (**cpp == '!') { + if (strcasecmp(*cpp + 1, "from")) { + fprintf(stderr, "Missing from after !\n"); + return NULL; + } + ipn.in_flags |= IPN_NOTSRC; + } + if ((ipn.in_flags & IPN_NOTSRC) && + (ipn.in_redir & (NAT_MAP|NAT_MAPBLK))) { + fprintf(stderr, "Cannot use '! from' with map\n"); + return NULL; + } + + ipn.in_flags |= IPN_FILTER; + cpp++; + if (ipn.in_redir == NAT_REDIRECT) { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_srcip, + (u_32_t *)&ipn.in_srcmsk, linenum) == -1) + return NULL; + + if (ports(&cpp, proto, &ipn.in_sport, + &ipn.in_scmp, &ipn.in_stop, linenum)) + return NULL; + } else { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_inip, + (u_32_t *)&ipn.in_inmsk, linenum) == -1) + return NULL; + + if (ports(&cpp, proto, &ipn.in_dport, + &ipn.in_dcmp, &ipn.in_dtop, linenum)) + return NULL; + } + + if (!strcmp(*cpp, "!")) { + cpp++; + ipn.in_flags |= IPN_NOTDST; + } else if (**cpp == '!') { + (*cpp)++; + ipn.in_flags |= IPN_NOTDST; + } + + if (strcasecmp(*cpp, "to")) { + fprintf(stderr, "%d: unexpected keyword (%s) - to\n", + linenum, *cpp); + return NULL; + } + if ((ipn.in_flags & IPN_NOTDST) && + (ipn.in_redir & (NAT_REDIRECT))) { + fprintf(stderr, "Cannot use '! to' with rdr\n"); + return NULL; + } + + if (!*++cpp) { + fprintf(stderr, "%d: missing host after to\n", linenum); + return NULL; + } + if (ipn.in_redir == NAT_REDIRECT) { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_outip, + (u_32_t *)&ipn.in_outmsk, linenum)) + return NULL; + + if (ports(&cpp, proto, &ipn.in_dport, + &ipn.in_dcmp, &ipn.in_dtop, linenum)) + return NULL; + ipn.in_pmin = htons(ipn.in_dport); + } else { + if (hostmask(&cpp, proto, NULL, + (u_32_t *)&ipn.in_srcip, + (u_32_t *)&ipn.in_srcmsk, linenum)) + return NULL; + + if (ports(&cpp, proto, &ipn.in_sport, + &ipn.in_scmp, &ipn.in_stop, linenum)) + return NULL; + } + } else { + s = *cpp; + if (!s) + return NULL; + t = strchr(s, '/'); + if (!t) + return NULL; + *t++ = '\0'; + if (ipn.in_redir == NAT_REDIRECT) { + if (hostnum((u_32_t *)&ipn.in_outip, s, linenum, NULL)) + return NULL; + if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) { + return NULL; + } + } else { + if (hostnum((u_32_t *)&ipn.in_inip, s, linenum, NULL)) + return NULL; + if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) { + return NULL; + } + } + cpp++; + if (!*cpp) + return NULL; + } + + if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) { + if (strcasecmp(*cpp, "port")) { + fprintf(stderr, "%d: missing fields - 1st port\n", + linenum); + return NULL; + } + + cpp++; + + if (!*cpp) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + + if (ISDIGIT(**cpp) && (s = strchr(*cpp, '-'))) + *s++ = '\0'; + else + s = NULL; + + if (!portnum(*cpp, proto, &ipn.in_pmin, linenum)) + return NULL; + ipn.in_pmin = htons(ipn.in_pmin); + cpp++; + + if (!strcmp(*cpp, "-")) { + cpp++; + s = *cpp++; + } + + if (s) { + if (!portnum(s, proto, &ipn.in_pmax, linenum)) + return NULL; + ipn.in_pmax = htons(ipn.in_pmax); + } else + ipn.in_pmax = ipn.in_pmin; + } + + if (!*cpp) { + fprintf(stderr, "%d: missing fields (->)\n", linenum); + return NULL; + } + if (strcmp(*cpp, "->")) { + fprintf(stderr, "%d: missing ->\n", linenum); + return NULL; + } + cpp++; + + if (!*cpp) { + fprintf(stderr, "%d: missing fields (%s)\n", + linenum, ipn.in_redir ? "destination" : "target"); + return NULL; + } + + if (ipn.in_redir == NAT_MAP) { + if (!strcasecmp(*cpp, "range")) { + cpp++; + ipn.in_flags |= IPN_IPRANGE; + if (!*cpp) { + fprintf(stderr, "%d: missing fields (%s)\n", + linenum, + ipn.in_redir ? "destination":"target"); + return NULL; + } + } + } + + if (ipn.in_flags & IPN_IPRANGE) { + dnetm = strrchr(*cpp, '-'); + if (dnetm == NULL) { + cpp++; + if (*cpp && !strcmp(*cpp, "-") && *(cpp + 1)) + dnetm = *(cpp + 1); + } else + *dnetm++ = '\0'; + if (dnetm == NULL || *dnetm == '\0') { + fprintf(stderr, + "%d: desination range not specified\n", + linenum); + return NULL; + } + } else if (ipn.in_redir != NAT_REDIRECT) { + dnetm = strrchr(*cpp, '/'); + if (dnetm == NULL) { + cpp++; + if (*cpp && !strcasecmp(*cpp, "netmask")) + dnetm = *++cpp; + } + if (dnetm == NULL) { + fprintf(stderr, + "%d: missing fields (dest netmask)\n", + linenum); + return NULL; + } + if (*dnetm == '/') + *dnetm++ = '\0'; + } + + if (ipn.in_redir == NAT_REDIRECT) { + dnetm = strchr(*cpp, ','); + if (dnetm != NULL) { + ipn.in_flags |= IPN_SPLIT; + *dnetm++ = '\0'; + } + if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum, NULL)) + return NULL; + } else { + if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum, NULL)) + return NULL; + } + cpp++; + + if (ipn.in_redir & NAT_MAPBLK) { + if (*cpp && strcasecmp(*cpp, "ports")) { + fprintf(stderr, + "%d: expected \"ports\" - got \"%s\"\n", + linenum, *cpp); + return NULL; + } + cpp++; + if (*cpp) { + ipn.in_pmin = atoi(*cpp); + cpp++; + } else + ipn.in_pmin = 0; + } else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) { + if (*cpp && strrchr(*cpp, '/') != NULL) { + fprintf(stderr, "%d: No netmask supported in %s\n", + linenum, "destination host for redirect"); + return NULL; + } + /* If it's a in_redir, expect target port */ + + if (!*cpp || strcasecmp(*cpp, "port")) { + fprintf(stderr, "%d: missing fields - 2nd port (%s)\n", + linenum, *cpp); + return NULL; + } + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + if (!portnum(*cpp, proto, &ipn.in_pnext, linenum)) + return NULL; + ipn.in_pnext = htons(ipn.in_pnext); + cpp++; + } + if (dnetm && *dnetm == '/') + *dnetm++ = '\0'; + + if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) { + if (ipn.in_flags & IPN_IPRANGE) { + if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm, + linenum, NULL) == -1) + return NULL; + } else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk)) + return NULL; + } else { + if (ipn.in_flags & IPN_SPLIT) { + if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm, + linenum, NULL) == -1) + return NULL; + } else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk)) + return NULL; + if (!*cpp) { + ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */ + proto = "tcp"; + } else { + if (!strcasecmp(*cpp, "tcp")) + ipn.in_flags |= IPN_TCP; + else if (!strcasecmp(*cpp, "udp")) + ipn.in_flags |= IPN_UDP; + else if (!strcasecmp(*cpp, "tcp/udp")) + ipn.in_flags |= IPN_TCPUDP; + else if (!strcasecmp(*cpp, "tcpudp")) + ipn.in_flags |= IPN_TCPUDP; + else if (!strcasecmp(*cpp, "ip")) + ipn.in_flags |= IPN_ANY; + else { + ipn.in_flags |= IPN_ANY; + ipn.in_p = getproto(*cpp); + } + proto = *cpp; + cpp++; + + if (*cpp && !strcasecmp(*cpp, "round-robin")) { + cpp++; + ipn.in_flags |= IPN_ROUNDR; + } + + if (*cpp && !strcasecmp(*cpp, "frag")) { + cpp++; + ipn.in_flags |= IPN_FRAG; + } + + if (*cpp && !strcasecmp(*cpp, "age")) { + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: age with no parameters\n", + linenum); + return NULL; + } + + ipn.in_age[0] = atoi(*cpp); + s = strchr(*cpp, '/'); + if (s != NULL) + ipn.in_age[1] = atoi(s + 1); + else + ipn.in_age[1] = ipn.in_age[0]; + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "mssclamp")) { + cpp++; + if (*cpp) { + ipn.in_mssclamp = atoi(*cpp); + cpp++; + } else { + fprintf(stderr, + "%d: mssclamp with no parameters\n", + linenum); + return NULL; + } + } + + if (*cpp) { + fprintf(stderr, + "%d: extra junk at the end of rdr: %s\n", + linenum, *cpp); + return NULL; + } + } + } + + if (!(ipn.in_flags & IPN_SPLIT)) + ipn.in_inip &= ipn.in_inmsk; + if ((ipn.in_flags & IPN_IPRANGE) == 0) + ipn.in_outip &= ipn.in_outmsk; + ipn.in_srcip &= ipn.in_srcmsk; + + if ((ipn.in_redir & NAT_MAPBLK) != 0) + nat_setgroupmap(&ipn); + + if (*cpp && !strcasecmp(*cpp, "frag")) { + cpp++; + ipn.in_flags |= IPN_ROUNDR; + } + + if (!*cpp) + return &ipn; + + if (ipn.in_redir != NAT_BIMAP && !strcasecmp(*cpp, "proxy")) { + if (ipn.in_redir == NAT_BIMAP) { + fprintf(stderr, "%d: cannot use proxy with bimap\n", + linenum); + return NULL; + } + + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing parameter for \"proxy\"\n", + linenum); + return NULL; + } + dport = NULL; + + if (!strcasecmp(*cpp, "port")) { + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing parameter for \"port\"\n", + linenum); + return NULL; + } + + dport = *cpp; + cpp++; + + if (!*cpp) { + fprintf(stderr, + "%d: missing parameter for \"proxy\"\n", + linenum); + return NULL; + } + } else { + fprintf(stderr, + "%d: missing keyword \"port\"\n", linenum); + return NULL; + } + + if ((proto = strchr(*cpp, '/'))) { + *proto++ = '\0'; + ipn.in_p = getproto(proto); + } else + ipn.in_p = 0; + + if (dport && !portnum(dport, proto, &ipn.in_dport, linenum)) + return NULL; + ipn.in_dport = htons(ipn.in_dport); + + (void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel)); + cpp++; + + if (*cpp) { + fprintf(stderr, + "%d: too many parameters for \"proxy\"\n", + linenum); + return NULL; + } + return &ipn; + } + + + if (!strcasecmp(*cpp, "icmpidmap")) { + + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: icmpidmap misses protocol and range\n", + linenum); + return NULL; + }; + + if (!strcasecmp(*cpp, "icmp")) + ipn.in_flags = IPN_ICMPQUERY; + else { + fprintf(stderr, "%d: icmpidmap only valid for icmp\n", + linenum); + return NULL; + } + cpp++; + + if (!*cpp) { + fprintf(stderr, "%d: no icmp id argument found\n", + linenum); + return NULL; + } + + if (!(t = strchr(*cpp, ':'))) { + fprintf(stderr, + "%d: no icmp id range detected in \"%s\"\n", + linenum, *cpp); + return NULL; + } + *t++ = '\0'; + + if (!icmpidnum(*cpp, &ipn.in_pmin, linenum) || + !icmpidnum(t, &ipn.in_pmax, linenum)) + return NULL; + } else if (!strcasecmp(*cpp, "portmap")) { + if (ipn.in_redir == NAT_BIMAP) { + fprintf(stderr, "%d: cannot use proxy with bimap\n", + linenum); + return NULL; + } + cpp++; + if (!*cpp) { + fprintf(stderr, + "%d: missing expression following portmap\n", + linenum); + return NULL; + } + + if (!strcasecmp(*cpp, "tcp")) + ipn.in_flags |= IPN_TCP; + else if (!strcasecmp(*cpp, "udp")) + ipn.in_flags |= IPN_UDP; + else if (!strcasecmp(*cpp, "tcpudp")) + ipn.in_flags |= IPN_TCPUDP; + else if (!strcasecmp(*cpp, "tcp/udp")) + ipn.in_flags |= IPN_TCPUDP; + else { + fprintf(stderr, + "%d: expected protocol name - got \"%s\"\n", + linenum, *cpp); + return NULL; + } + proto = *cpp; + cpp++; + + if (!*cpp) { + fprintf(stderr, "%d: no port range found\n", linenum); + return NULL; + } + + if (!strcasecmp(*cpp, "auto")) { + ipn.in_flags |= IPN_AUTOPORTMAP; + ipn.in_pmin = htons(1024); + ipn.in_pmax = htons(65535); + nat_setgroupmap(&ipn); + } else { + if (!(t = strchr(*cpp, ':'))) { + fprintf(stderr, + "%d: no port range in \"%s\"\n", + linenum, *cpp); + return NULL; + } + *t++ = '\0'; + if (!portnum(*cpp, proto, &ipn.in_pmin, linenum) || + !portnum(t, proto, &ipn.in_pmax, linenum)) + return NULL; + } + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "round-robin")) { + cpp++; + ipn.in_flags |= IPN_ROUNDR; + } + + if (*cpp && !strcasecmp(*cpp, "age")) { + cpp++; + if (!*cpp) { + fprintf(stderr, "%d: age with no parameters\n", + linenum); + return NULL; + } + s = strchr(*cpp, '/'); + if (s != NULL) + ipn.in_age[1] = atoi(s + 1); + else + ipn.in_age[1] = ipn.in_age[0]; + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "mssclamp")) { + cpp++; + if (*cpp) { + ipn.in_mssclamp = atoi(*cpp); + cpp++; + } else { + fprintf(stderr, "%d: mssclamp with no parameters\n", + linenum); + return NULL; + } + } + + if (*cpp) { + fprintf(stderr, "%d: extra junk at the end of the line: %s\n", + linenum, *cpp); + return NULL; + } + + ipn.in_pmin = htons(ipn.in_pmin); + ipn.in_pmax = htons(ipn.in_pmax); + return &ipn; +} + + +void natparsefile(fd, file, opts) +int fd; +char *file; +int opts; +{ + char line[512], *s; + ipnat_t *np; + FILE *fp; + int linenum = 0; + + if (strcmp(file, "-")) { + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "%s: open: %s\n", file, + STRERROR(errno)); + exit(1); + } + } else + fp = stdin; + + while (getline(line, sizeof(line) - 1, fp, &linenum)) { + line[sizeof(line) - 1] = '\0'; + if ((s = strchr(line, '\n'))) + *s = '\0'; + + if (!(np = natparse(line, linenum))) { + if (*line) + fprintf(stderr, "%d: syntax error in \"%s\"\n", + linenum, line); + } else { + if ((opts & OPT_VERBOSE) && np) + printnat(np, opts); + if (!(opts & OPT_DONOTHING)) { + if (!(opts & OPT_REMOVE)) { + if (ioctl(fd, SIOCADNAT, &np) == -1) + perror("ioctl(SIOCADNAT)"); + } else if (ioctl(fd, SIOCRMNAT, &np) == -1) + perror("ioctl(SIOCRMNAT)"); + } + } + } + if (fp != stdin) + fclose(fp); +} + + +int icmpidnum(str, id, linenum) +char *str; +u_short *id; +int linenum; +{ + int i; + + + i = atoi(str); + + if ((i<0) || (i>65535)) { + fprintf(stderr, "%d: invalid icmp id\"%s\".\n", linenum, str); + return 0; + } + + *id = (u_short)i; + + return 1; +} diff --git a/contrib/ipfilter/lib/ntomask.c b/contrib/ipfilter/lib/ntomask.c new file mode 100644 index 000000000000..415a5e867c9d --- /dev/null +++ b/contrib/ipfilter/lib/ntomask.c @@ -0,0 +1,38 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +int ntomask(v, nbits, ap) +int v, nbits; +u_32_t *ap; +{ + u_32_t mask; + + if (nbits < 0) + return -1; + + switch (v) + { + case 4 : + if (nbits > 32 || use_inet6 != 0) + return -1; + if (nbits == 0) { + mask = 0; + } else { + mask = 0xffffffff; + mask <<= (32 - nbits); + } + *ap = htonl(mask); + break; + + case 6 : + if ((nbits > 128) || (use_inet6 == 0)) + return -1; + fill6bits(nbits, ap); + break; + + default : + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/optname.c b/contrib/ipfilter/lib/optname.c new file mode 100644 index 000000000000..7fdcc57964d7 --- /dev/null +++ b/contrib/ipfilter/lib/optname.c @@ -0,0 +1,65 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optname.c,v 1.3 2001/06/09 17:09:24 darrenr Exp + */ + +#include "ipf.h" + + +u_32_t optname(cp, sp, linenum) +char ***cp; +u_short *sp; +int linenum; +{ + struct ipopt_names *io, *so; + u_long msk = 0; + u_short smsk = 0; + char *s; + int sec = 0; + + for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { + for (io = ionames; io->on_name; io++) + if (!strcasecmp(s, io->on_name)) { + msk |= io->on_bit; + break; + } + if (!io->on_name) { + fprintf(stderr, "%d: unknown IP option name %s\n", + linenum, s); + return 0; + } + if (!strcasecmp(s, "sec-class")) + sec = 1; + } + + if (sec && !*(*cp + 1)) { + fprintf(stderr, "%d: missing security level after sec-class\n", + linenum); + return 0; + } + + if (sec) { + (*cp)++; + for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { + for (so = secclass; so->on_name; so++) + if (!strcasecmp(s, so->on_name)) { + smsk |= so->on_bit; + break; + } + if (!so->on_name) { + fprintf(stderr, + "%d: no such security level: %s\n", + linenum, s); + return 0; + } + } + if (smsk) + *sp = smsk; + } + return msk; +} diff --git a/contrib/ipfilter/lib/optprint.c b/contrib/ipfilter/lib/optprint.c new file mode 100644 index 000000000000..261a75cb0220 --- /dev/null +++ b/contrib/ipfilter/lib/optprint.c @@ -0,0 +1,79 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optprint.c,v 1.6 2002/07/13 15:59:49 darrenr Exp + */ +#include "ipf.h" + + +void optprint(sec, optmsk, optbits) +u_short *sec; +u_long optmsk, optbits; +{ + u_short secmsk = sec[0], secbits = sec[1]; + struct ipopt_names *io, *so; + char *s; + + s = " opt "; + for (io = ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) == (io->on_bit & optbits))) { + if ((io->on_value != IPOPT_SECURITY) || + (!secmsk && !secbits)) { + printf("%s%s", s, io->on_name); + if (io->on_value == IPOPT_SECURITY) + io++; + s = ","; + } + } + + + if (secmsk & secbits) { + printf("%ssec-class", s); + s = " "; + for (so = secclass; so->on_name; so++) + if ((secmsk & so->on_bit) && + ((so->on_bit & secmsk) == (so->on_bit & secbits))) { + printf("%s%s", s, so->on_name); + s = ","; + } + } + + if ((optmsk && (optmsk != optbits)) || + (secmsk && (secmsk != secbits))) { + s = " "; + printf(" not opt"); + if (optmsk != optbits) { + for (io = ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) != + (io->on_bit & optbits))) { + if ((io->on_value != IPOPT_SECURITY) || + (!secmsk && !secbits)) { + printf("%s%s", s, io->on_name); + s = ","; + if (io->on_value == + IPOPT_SECURITY) + io++; + } else + io++; + } + } + + if (secmsk != secbits) { + printf("%ssec-class", s); + s = " "; + for (so = secclass; so->on_name; so++) + if ((so->on_bit & secmsk) && + ((so->on_bit & secmsk) != + (so->on_bit & secbits))) { + printf("%s%s", s, so->on_name); + s = ","; + } + } + } +} diff --git a/contrib/ipfilter/lib/optprintv6.c b/contrib/ipfilter/lib/optprintv6.c new file mode 100644 index 000000000000..75e0fd0615f5 --- /dev/null +++ b/contrib/ipfilter/lib/optprintv6.c @@ -0,0 +1,47 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optprintv6.c,v 1.2 2003/04/30 00:39:39 darrenr Exp + */ +#include "ipf.h" + + +#ifdef USE_INET6 + +void optprintv6(sec, optmsk, optbits) +u_short *sec; +u_long optmsk, optbits; +{ + u_short secmsk = sec[0], secbits = sec[1]; + struct ipopt_names *io; + char *s; + + s = " v6hdrs "; + for (io = v6ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) == (io->on_bit & optbits))) { + printf("%s%s", s, io->on_name); + s = ","; + } + + if ((optmsk && (optmsk != optbits)) || + (secmsk && (secmsk != secbits))) { + s = " "; + printf(" not v6hdrs"); + if (optmsk != optbits) { + for (io = v6ionames; io->on_name; io++) + if ((io->on_bit & optmsk) && + ((io->on_bit & optmsk) != + (io->on_bit & optbits))) { + printf("%s%s", s, io->on_name); + s = ","; + } + } + + } +} +#endif diff --git a/contrib/ipfilter/lib/optvalue.c b/contrib/ipfilter/lib/optvalue.c new file mode 100644 index 000000000000..dc9448d1b42e --- /dev/null +++ b/contrib/ipfilter/lib/optvalue.c @@ -0,0 +1,34 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: optvalue.c,v 1.2 2002/01/28 06:50:47 darrenr Exp + */ +#include "ipf.h" + + +u_32_t getoptbyname(optname) +char *optname; +{ + struct ipopt_names *io; + + for (io = ionames; io->on_name; io++) + if (!strcasecmp(optname, io->on_name)) + return io->on_bit; + return -1; +} + + +u_32_t getoptbyvalue(optval) +int optval; +{ + struct ipopt_names *io; + + for (io = ionames; io->on_name; io++) + if (io->on_value == optval) + return io->on_bit; + return -1; +} diff --git a/contrib/ipfilter/lib/parse.c b/contrib/ipfilter/lib/parse.c new file mode 100644 index 000000000000..4cf69abe88f8 --- /dev/null +++ b/contrib/ipfilter/lib/parse.c @@ -0,0 +1,754 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: parse.c,v 1.34.2.1 2004/12/09 19:41:21 darrenr Exp + */ +#include +#include "ipf.h" +#include "opts.h" + +static frentry_t *fp = NULL; + +/* parse() + * + * parse a line read from the input filter rule file + */ +struct frentry *parse(line, linenum) +char *line; +int linenum; +{ + static fripf_t fip; + char *cps[31], **cpp, *endptr, *proto = NULL, *s; + struct protoent *p = NULL; + int i, cnt = 1, j; + u_int k; + + if (fp == NULL) { + fp = malloc(sizeof(*fp)); + if (fp == NULL) + return NULL; + } + + while (*line && ISSPACE(*line)) + line++; + if (!*line) + return NULL; + + bzero((char *)fp, sizeof(*fp)); + bzero((char *)&fip, sizeof(fip)); + fp->fr_v = use_inet6 ? 6 : 4; + fp->fr_ipf = &fip; + fp->fr_dsize = sizeof(fip); + fp->fr_ip.fi_v = fp->fr_v; + fp->fr_mip.fi_v = 0xf; + fp->fr_type = FR_T_NONE; + fp->fr_loglevel = 0xffff; + fp->fr_isc = (void *)-1; + fp->fr_tag = FR_NOTAG; + + /* + * break line up into max of 20 segments + */ + if (opts & OPT_DEBUG) + fprintf(stderr, "parse [%s]\n", line); + for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) + cps[++i] = strtok(NULL, " \b\t\r\n"); + cps[i] = NULL; + + if (cnt < 3) { + fprintf(stderr, "%d: not enough segments in line\n", linenum); + return NULL; + } + + cpp = cps; + /* + * The presence of an '@' followed by a number gives the position in + * the current rule list to insert this one. + */ + if (**cpp == '@') + fp->fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1; + + /* + * Check the first keyword in the rule and any options that are + * expected to follow it. + */ + if (!strcasecmp("block", *cpp)) { + fp->fr_flags |= FR_BLOCK; + if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) && + (i = 19)) + fp->fr_flags |= FR_FAKEICMP; + else if (!strncasecmp(*(cpp+1), "return-icmp", 11) && (i = 11)) + fp->fr_flags |= FR_RETICMP; + if (fp->fr_flags & FR_RETICMP) { + cpp++; + if (strlen(*cpp) == i) { + if (*(cpp + 1) && **(cpp +1) == '(') { + cpp++; + i = 0; + } else + i = -1; + } + + /* + * The ICMP code is not required to follow in ()'s + */ + if ((i >= 0) && (*(*cpp + i) == '(')) { + i++; + j = icmpcode(*cpp + i); + if (j == -1) { + fprintf(stderr, + "%d: unrecognised icmp code %s\n", + linenum, *cpp + 20); + return NULL; + } + fp->fr_icode = j; + } + } else if (!strncasecmp(*(cpp+1), "return-rst", 10)) { + fp->fr_flags |= FR_RETRST; + cpp++; + } + } else if (!strcasecmp("count", *cpp)) { + fp->fr_flags |= FR_ACCOUNT; + } else if (!strcasecmp("pass", *cpp)) { + fp->fr_flags |= FR_PASS; + } else if (!strcasecmp("auth", *cpp)) { + fp->fr_flags |= FR_AUTH; + } else if (fp->fr_arg != 0) { + printf("skip %u", fp->fr_arg); + } else if (!strcasecmp("preauth", *cpp)) { + fp->fr_flags |= FR_PREAUTH; + } else if (!strcasecmp("nomatch", *cpp)) { + fp->fr_flags |= FR_NOMATCH; + } else if (!strcasecmp("skip", *cpp)) { + cpp++; + if (ratoui(*cpp, &k, 0, UINT_MAX)) + fp->fr_arg = k; + else { + fprintf(stderr, "%d: integer must follow skip\n", + linenum); + return NULL; + } + } else if (!strcasecmp("log", *cpp)) { + fp->fr_flags |= FR_LOG; + if (!strcasecmp(*(cpp+1), "body")) { + fp->fr_flags |= FR_LOGBODY; + cpp++; + } + if (!strcasecmp(*(cpp+1), "first")) { + fp->fr_flags |= FR_LOGFIRST; + cpp++; + } + if (*cpp && !strcasecmp(*(cpp+1), "or-block")) { + fp->fr_flags |= FR_LOGORBLOCK; + cpp++; + } + if (!strcasecmp(*(cpp+1), "level")) { + cpp++; + if (loglevel(cpp, &fp->fr_loglevel, linenum) == -1) + return NULL; + cpp++; + } + } else { + /* + * Doesn't start with one of the action words + */ + fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum); + return NULL; + } + + /* + * Get the direction for filtering. Impose restrictions on direction + * if blocking with returning ICMP or an RST has been requested. + */ + if (!strcasecmp("in", *cpp)) + fp->fr_flags |= FR_INQUE; + else if (!strcasecmp("out", *cpp)) { + fp->fr_flags |= FR_OUTQUE; + if (fp->fr_flags & FR_RETICMP) { + fprintf(stderr, + "%d: Can only use return-icmp with 'in'\n", + linenum); + return NULL; + } else if (fp->fr_flags & FR_RETRST) { + fprintf(stderr, + "%d: Can only use return-rst with 'in'\n", + linenum); + return NULL; + } + } + if (!*++cpp) { + fprintf(stderr, "%d: missing source specification\n", linenum); + return NULL; + } + + if (!strcasecmp("log", *cpp)) { + if (!*++cpp) { + fprintf(stderr, "%d: missing source specification\n", + linenum); + return NULL; + } + if (FR_ISPASS(fp->fr_flags)) + fp->fr_flags |= FR_LOGP; + else if (FR_ISBLOCK(fp->fr_flags)) + fp->fr_flags |= FR_LOGB; + if (*cpp && !strcasecmp(*cpp, "body")) { + fp->fr_flags |= FR_LOGBODY; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "first")) { + fp->fr_flags |= FR_LOGFIRST; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "or-block")) { + if (!FR_ISPASS(fp->fr_flags)) { + fprintf(stderr, + "%d: or-block must be used with pass\n", + linenum); + return NULL; + } + fp->fr_flags |= FR_LOGORBLOCK; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "level")) { + if (loglevel(cpp, &fp->fr_loglevel, linenum) == -1) + return NULL; + cpp++; + cpp++; + } + } + + if (*cpp && !strcasecmp("quick", *cpp)) { + if (fp->fr_arg != 0) { + fprintf(stderr, "%d: cannot use skip with quick\n", + linenum); + return NULL; + } + cpp++; + fp->fr_flags |= FR_QUICK; + } + + /* + * Parse rule options that are available if a rule is tied to an + * interface. + */ + *fp->fr_ifname = '\0'; + *fp->fr_oifname = '\0'; + if (*cpp && !strcasecmp(*cpp, "on")) { + if (!*++cpp) { + fprintf(stderr, "%d: interface name missing\n", + linenum); + return NULL; + } + (void)strncpy(fp->fr_ifname, *cpp, IFNAMSIZ-1); + fp->fr_ifname[IFNAMSIZ-1] = '\0'; + cpp++; + if (!*cpp) { + if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) { + fprintf(stderr, + "%d: %s can only be used with TCP\n", + linenum, "return-rst"); + return NULL; + } + return fp; + } + + if (!strcasecmp(*cpp, "out-via")) { + if (fp->fr_flags & FR_OUTQUE) { + fprintf(stderr, + "out-via must be used with in\n"); + return NULL; + } + cpp++; + (void)strncpy(fp->fr_oifname, *cpp, IFNAMSIZ-1); + fp->fr_oifname[IFNAMSIZ-1] = '\0'; + cpp++; + } else if (!strcasecmp(*cpp, "in-via")) { + if (fp->fr_flags & FR_INQUE) { + fprintf(stderr, + "in-via must be used with out\n"); + return NULL; + } + cpp++; + (void)strncpy(fp->fr_oifname, *cpp, IFNAMSIZ-1); + fp->fr_oifname[IFNAMSIZ-1] = '\0'; + cpp++; + } + + if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) { + cpp++; + if (to_interface(&fp->fr_dif, *cpp, linenum)) + return NULL; + cpp++; + } + if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) { + cpp++; + if (to_interface(&fp->fr_tif, *cpp, linenum)) + return NULL; + cpp++; + } else if (*cpp && !strcasecmp(*cpp, "fastroute")) { + if (!(fp->fr_flags & FR_INQUE)) { + fprintf(stderr, + "can only use %s with 'in'\n", + "fastroute"); + return NULL; + } + fp->fr_flags |= FR_FASTROUTE; + cpp++; + } + + /* + * Set the "other" interface name. Lets you specify both + * inbound and outbound interfaces for state rules. Do not + * prevent both interfaces from being the same. + */ + strcpy(fp->fr_ifnames[3], "*"); + if ((*cpp != NULL) && (*(cpp + 1) != NULL) && + ((((fp->fr_flags & FR_INQUE) != 0) && + (strcasecmp(*cpp, "out-via") == 0)) || + (((fp->fr_flags & FR_OUTQUE) != 0) && + (strcasecmp(*cpp, "in-via") == 0)))) { + cpp++; + + s = strchr(*cpp, ','); + if (s != NULL) { + *s++ = '\0'; + (void)strncpy(fp->fr_ifnames[3], s, + IFNAMSIZ - 1); + fp->fr_ifnames[3][IFNAMSIZ - 1] = '\0'; + } + + (void)strncpy(fp->fr_ifnames[2], *cpp, IFNAMSIZ - 1); + fp->fr_ifnames[2][IFNAMSIZ - 1] = '\0'; + cpp++; + } else + strcpy(fp->fr_ifnames[2], "*"); + + } + + if (*cpp && !strcasecmp(*cpp, "tos")) { + if (!*++cpp) { + fprintf(stderr, "%d: tos missing value\n", linenum); + return NULL; + } + fp->fr_tos = strtol(*cpp, NULL, 0); + fp->fr_mip.fi_tos = 0xff; + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "ttl")) { + if (!*++cpp) { + fprintf(stderr, "%d: ttl missing hopcount value\n", + linenum); + return NULL; + } + if (ratoi(*cpp, &i, 0, 255)) + fp->fr_ttl = i; + else { + fprintf(stderr, "%d: invalid ttl (%s)\n", + linenum, *cpp); + return NULL; + } + fp->fr_mip.fi_ttl = 0xff; + cpp++; + } + + /* + * check for "proto " only decode udp/tcp/icmp as protoname + */ + if (*cpp && !strcasecmp(*cpp, "proto")) { + if (!*++cpp) { + fprintf(stderr, "%d: protocol name missing\n", linenum); + return NULL; + } + fp->fr_type = FR_T_IPF; + proto = *cpp++; + if (!strcasecmp(proto, "tcp/udp")) { + fp->fr_flx |= FI_TCPUDP; + fp->fr_mflx |= FI_TCPUDP; + } else if (use_inet6 && !strcasecmp(proto, "icmp")) { + fprintf(stderr, +"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n", + linenum); + return NULL; + } else { + fp->fr_proto = getproto(proto); + fp->fr_mip.fi_p = 0xff; + } + } + if ((fp->fr_proto != IPPROTO_TCP) && + ((fp->fr_flags & FR_RETMASK) == FR_RETRST)) { + fprintf(stderr, "%d: %s can only be used with TCP\n", + linenum, "return-rst"); + return NULL; + } + + /* + * get the from host and bit mask to use against packets + */ + + if (!*cpp) { + fprintf(stderr, "%d: missing source specification\n", linenum); + return NULL; + } + if (!strcasecmp(*cpp, "all")) { + cpp++; + if (!*cpp) { + if (fp->fr_type == FR_T_NONE) { + fp->fr_dsize = 0; + fp->fr_data = NULL; + } + return fp; + } + fp->fr_type = FR_T_IPF; +#ifdef IPFILTER_BPF + } else if (!strcmp(*cpp, "{")) { + struct bpf_program bpf; + struct pcap *p; + char **cp; + u_32_t l; + + if (fp->fr_type != FR_T_NONE) { + fprintf(stderr, + "%d: cannot mix BPF/ipf matching\n", linenum); + return NULL; + } + fp->fr_type = FR_T_BPFOPC; + cpp++; + if (!strncmp(*cpp, "0x", 2)) { + fp->fr_data = malloc(4); + for (cp = cpp, i = 0; *cp; cp++, i++) { + if (!strcmp(*cp, "}")) + break; + fp->fr_data = realloc(fp->fr_data, + (i + 1) * 4); + l = strtoul(*cp, NULL, 0); + ((u_32_t *)fp->fr_data)[i] = l; + } + if (!*cp) { + fprintf(stderr, "Missing closing '}'\n"); + return NULL; + } + fp->fr_dsize = i * sizeof(l); + bpf.bf_insns = fp->fr_data; + bpf.bf_len = fp->fr_dsize / sizeof(struct bpf_insn); + } else { + for (cp = cpp; *cp; cp++) { + if (!strcmp(*cp, "}")) + break; + (*cp)[-1] = ' '; + } + if (!*cp) { + fprintf(stderr, "Missing closing '}'\n"); + return NULL; + } + + bzero((char *)&bpf, sizeof(bpf)); + p = pcap_open_dead(DLT_RAW, 1); + if (!p) { + fprintf(stderr, "pcap_open_dead failed\n"); + return NULL; + } + + if (pcap_compile(p, &bpf, *cpp, 1, 0xffffffff)) { + pcap_perror(p, "ipf"); + pcap_close(p); + fprintf(stderr, "pcap parsing failed\n"); + return NULL; + } + pcap_close(p); + fp->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn); + fp->fr_data = bpf.bf_insns; + if (!bpf_validate(fp->fr_data, bpf.bf_len)) { + fprintf(stderr, "BPF validation failed\n"); + return NULL; + } + if (opts & OPT_DEBUG) + bpf_dump(&bpf, 0); + } + cpp = cp; + (*cpp)++; +#endif + } else { + fp->fr_type = FR_T_IPF; + + if (strcasecmp(*cpp, "from")) { + fprintf(stderr, "%d: unexpected keyword (%s) - from\n", + linenum, *cpp); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: missing host after from\n", + linenum); + return NULL; + } + if (**cpp == '!') { + fp->fr_flags |= FR_NOTSRCIP; + (*cpp)++; + } else if (!strcmp(*cpp, "!")) { + fp->fr_flags |= FR_NOTSRCIP; + cpp++; + } + + s = *cpp; + i = hostmask(&cpp, proto, fp->fr_ifname, (u_32_t *)&fp->fr_src, + (u_32_t *)&fp->fr_smsk, linenum); + if (i == -1) + return NULL; + if (*fp->fr_ifname && !strcasecmp(s, fp->fr_ifname)) + fp->fr_satype = FRI_DYNAMIC; + if (i == 1) { + if (fp->fr_v == 6) { + fprintf(stderr, + "can only use pools with ipv4\n"); + return NULL; + } + fp->fr_satype = FRI_LOOKUP; + } + + if (ports(&cpp, proto, &fp->fr_sport, &fp->fr_scmp, + &fp->fr_stop, linenum)) + return NULL; + + if (!*cpp) { + fprintf(stderr, "%d: missing to fields\n", linenum); + return NULL; + } + + /* + * do the same for the to field (destination host) + */ + if (strcasecmp(*cpp, "to")) { + fprintf(stderr, "%d: unexpected keyword (%s) - to\n", + linenum, *cpp); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: missing host after to\n", linenum); + return NULL; + } + + if (**cpp == '!') { + fp->fr_flags |= FR_NOTDSTIP; + (*cpp)++; + } else if (!strcmp(*cpp, "!")) { + fp->fr_flags |= FR_NOTDSTIP; + cpp++; + } + + s = *cpp; + i = hostmask(&cpp, proto, fp->fr_ifname, (u_32_t *)&fp->fr_dst, + (u_32_t *)&fp->fr_dmsk, linenum); + if (i == -1) + return NULL; + if (*fp->fr_ifname && !strcasecmp(s, fp->fr_ifname)) + fp->fr_datype = FRI_DYNAMIC; + if (i == 1) { + if (fp->fr_v == 6) { + fprintf(stderr, + "can only use pools with ipv4\n"); + return NULL; + } + fp->fr_datype = FRI_LOOKUP; + } + + if (ports(&cpp, proto, &fp->fr_dport, &fp->fr_dcmp, + &fp->fr_dtop, linenum)) + return NULL; + } + + if (fp->fr_type == FR_T_IPF) { + /* + * check some sanity, make sure we don't have icmp checks + * with tcp or udp or visa versa. + */ + if (fp->fr_proto && (fp->fr_dcmp || fp->fr_scmp) && + fp->fr_proto != IPPROTO_TCP && + fp->fr_proto != IPPROTO_UDP) { + fprintf(stderr, + "%d: port operation on non tcp/udp\n",linenum); + return NULL; + } + if (fp->fr_icmp && fp->fr_proto != IPPROTO_ICMP) { + fprintf(stderr, + "%d: icmp comparisons on wrong protocol\n", + linenum); + return NULL; + } + + if (!*cpp) + return fp; + + if (*cpp && (fp->fr_type == FR_T_IPF) && + !strcasecmp(*cpp, "flags")) { + if (!*++cpp) { + fprintf(stderr, "%d: no flags present\n", + linenum); + return NULL; + } + fp->fr_tcpf = tcp_flags(*cpp, &fp->fr_tcpfm, linenum); + cpp++; + } + + /* + * extras... + */ + if ((fp->fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") || + !strcasecmp(*cpp, "and"))) + if (extras(&cpp, fp, linenum)) + return NULL; + + /* + * icmp types for use with the icmp protocol + */ + if (*cpp && !strcasecmp(*cpp, "icmp-type")) { + if (fp->fr_proto != IPPROTO_ICMP && + fp->fr_proto != IPPROTO_ICMPV6) { + fprintf(stderr, + "%d: icmp with wrong protocol (%d)\n", + linenum, fp->fr_proto); + return NULL; + } + if (addicmp(&cpp, fp, linenum)) + return NULL; + fp->fr_icmp = htons(fp->fr_icmp); + fp->fr_icmpm = htons(fp->fr_icmpm); + } + } + + /* + * Keep something... + */ + while (*cpp && !strcasecmp(*cpp, "keep")) + if (addkeep(&cpp, fp, linenum)) + return NULL; + + /* + * This is here to enforce the old interface binding behaviour. + * That is, "on X" is equivalent to " on X -via -,X" + */ + if (fp->fr_flags & FR_KEEPSTATE) { + if (*fp->fr_ifnames[0] && !*fp->fr_ifnames[3]) { + bcopy(fp->fr_ifnames[0], fp->fr_ifnames[3], + sizeof(fp->fr_ifnames[3])); + strncpy(fp->fr_ifnames[2], "*", + sizeof(fp->fr_ifnames[3])); + } + } + + /* + * head of a new group ? + */ + if (*cpp && !strcasecmp(*cpp, "head")) { + if (fp->fr_arg != 0) { + fprintf(stderr, "%d: cannot use skip with head\n", + linenum); + return NULL; + } + if (!*++cpp) { + fprintf(stderr, "%d: head without group #\n", linenum); + return NULL; + } + if (strlen(*cpp) > FR_GROUPLEN) { + fprintf(stderr, "%d: head name too long #\n", linenum); + return NULL; + } + strncpy(fp->fr_grhead, *cpp, FR_GROUPLEN); + cpp++; + } + + /* + * reference to an already existing group ? + */ + if (*cpp && !strcasecmp(*cpp, "group")) { + if (!*++cpp) { + fprintf(stderr, "%d: group without group #\n", + linenum); + return NULL; + } + if (strlen(*cpp) > FR_GROUPLEN) { + fprintf(stderr, "%d: group name too long #\n", linenum); + return NULL; + } + strncpy(fp->fr_group, *cpp, FR_GROUPLEN); + cpp++; + } + + if (*cpp && !strcasecmp(*cpp, "tag")) { + if (!*++cpp) { + fprintf(stderr, "%d: tag id missing value\n", linenum); + return NULL; + } + fp->fr_tag = strtol(*cpp, NULL, 0); + cpp++; + } + + /* + * pps counter + */ + if (*cpp && !strcasecmp(*cpp, "pps")) { + if (!*++cpp) { + fprintf(stderr, "%d: pps without rate\n", linenum); + return NULL; + } + if (ratoui(*cpp, &k, 0, INT_MAX)) + fp->fr_pps = k; + else { + fprintf(stderr, "%d: invalid pps rate (%s)\n", + linenum, *cpp); + return NULL; + } + cpp++; + } + + /* + * leftovers...yuck + */ + if (*cpp && **cpp) { + fprintf(stderr, "%d: unknown words at end: [", linenum); + for (; *cpp; cpp++) + fprintf(stderr, "%s ", *cpp); + fprintf(stderr, "]\n"); + return NULL; + } + + /* + * lazy users... + */ + if (fp->fr_type == FR_T_IPF) { + if ((fp->fr_tcpf || fp->fr_tcpfm) && + (fp->fr_proto != IPPROTO_TCP)) { + fprintf(stderr, + "%d: TCP protocol not specified\n", linenum); + return NULL; + } + if (!(fp->fr_flx & FI_TCPUDP) && + (fp->fr_proto != IPPROTO_TCP) && + (fp->fr_proto != IPPROTO_UDP) && + (fp->fr_dcmp || fp->fr_scmp)) { + if (!fp->fr_proto) { + fp->fr_flx |= FI_TCPUDP; + fp->fr_mflx |= FI_TCPUDP; + } else { + fprintf(stderr, + "%d: port check for non-TCP/UDP\n", + linenum); + return NULL; + } + } + } + if (*fp->fr_oifname && strcmp(fp->fr_oifname, "*") && + !(fp->fr_flags & FR_KEEPSTATE)) { + fprintf(stderr, "%d: *-via must be used %s\n", + linenum, "with keep-state"); + return NULL; + } + return fp; +} diff --git a/contrib/ipfilter/lib/portname.c b/contrib/ipfilter/lib/portname.c new file mode 100644 index 000000000000..7c0fc8796d70 --- /dev/null +++ b/contrib/ipfilter/lib/portname.c @@ -0,0 +1,42 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: portname.c,v 1.7 2003/08/14 14:27:43 darrenr Exp + */ +#include "ipf.h" + + +char *portname(pr, port) +int pr, port; +{ + static char buf[32]; + struct protoent *p = NULL; + struct servent *sv = NULL, *sv1 = NULL; + + if ((opts & OPT_NORESOLVE) == 0) { + if (pr == -1) { + if ((sv = getservbyport(htons(port), "tcp"))) { + strncpy(buf, sv->s_name, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + sv1 = getservbyport(htons(port), "udp"); + sv = strncasecmp(buf, sv->s_name, strlen(buf)) ? + NULL : sv1; + } + if (sv) + return buf; + } else if ((pr != -2) && (p = getprotobynumber(pr))) { + if ((sv = getservbyport(htons(port), p->p_name))) { + strncpy(buf, sv->s_name, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + return buf; + } + } + } + + (void) sprintf(buf, "%d", port); + return buf; +} diff --git a/contrib/ipfilter/lib/portnum.c b/contrib/ipfilter/lib/portnum.c new file mode 100644 index 000000000000..284bbc954557 --- /dev/null +++ b/contrib/ipfilter/lib/portnum.c @@ -0,0 +1,64 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * + * Id: portnum.c,v 1.6.4.1 2004/12/09 19:41:22 darrenr Exp + */ + +#include + +#include "ipf.h" + + +/* + * find the port number given by the name, either from getservbyname() or + * straight atoi(). Return 1 on success, 0 on failure + */ +int portnum(name, proto, port, linenum) +char *name, *proto; +u_short *port; +int linenum; +{ + struct servent *sp, *sp2; + u_short p1 = 0; + int i; + + if (ISDIGIT(*name)) { + if (ratoi(name, &i, 0, USHRT_MAX)) { + *port = (u_short)i; + return 1; + } + fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name); + return 0; + } + if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) { + sp = getservbyname(name, proto); + if (sp) { + *port = ntohs(sp->s_port); + return 1; + } + fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name); + return 0; + } + sp = getservbyname(name, "tcp"); + if (sp) + p1 = sp->s_port; + sp2 = getservbyname(name, "udp"); + if (!sp || !sp2) { + fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n", + linenum, name); + return 0; + } + if (p1 != sp2->s_port) { + fprintf(stderr, "%d: %s %d/tcp is a different port to ", + linenum, name, p1); + fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port); + return 0; + } + *port = ntohs(p1); + return 1; +} diff --git a/contrib/ipfilter/lib/ports.c b/contrib/ipfilter/lib/ports.c new file mode 100644 index 000000000000..634dfeb6cab3 --- /dev/null +++ b/contrib/ipfilter/lib/ports.c @@ -0,0 +1,81 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ports.c,v 1.9.4.1 2004/12/09 19:41:22 darrenr Exp + */ + +#include + +#include "ipf.h" + + +/* + * check for possible presence of the port fields in the line + */ +int ports(seg, proto, pp, cp, tp, linenum) +char ***seg; +char *proto; +u_short *pp; +int *cp; +u_short *tp; +int linenum; +{ + int comp = -1; + + if (!*seg || !**seg || !***seg) + return 0; + if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) { + (*seg)++; + if (ISALNUM(***seg) && *(*seg + 2)) { + if (portnum(**seg, proto, pp, linenum) == 0) + return -1; + (*seg)++; + if (!strcmp(**seg, "<>")) + comp = FR_OUTRANGE; + else if (!strcmp(**seg, "><")) + comp = FR_INRANGE; + else { + fprintf(stderr, + "%d: unknown range operator (%s)\n", + linenum, **seg); + return -1; + } + (*seg)++; + if (**seg == NULL) { + fprintf(stderr, "%d: missing 2nd port value\n", + linenum); + return -1; + } + if (portnum(**seg, proto, tp, linenum) == 0) + return -1; + } else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq")) + comp = FR_EQUAL; + else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne")) + comp = FR_NEQUAL; + else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt")) + comp = FR_LESST; + else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt")) + comp = FR_GREATERT; + else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le")) + comp = FR_LESSTE; + else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge")) + comp = FR_GREATERTE; + else { + fprintf(stderr, "%d: unknown comparator (%s)\n", + linenum, **seg); + return -1; + } + if (comp != FR_OUTRANGE && comp != FR_INRANGE) { + (*seg)++; + if (portnum(**seg, proto, pp, linenum) == 0) + return -1; + } + *cp = comp; + (*seg)++; + } + return 0; +} diff --git a/contrib/ipfilter/lib/print_toif.c b/contrib/ipfilter/lib/print_toif.c new file mode 100644 index 000000000000..0e230cdb4780 --- /dev/null +++ b/contrib/ipfilter/lib/print_toif.c @@ -0,0 +1,32 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: print_toif.c,v 1.8 2002/01/28 06:50:47 darrenr Exp + */ + +#include "ipf.h" + + +void print_toif(tag, fdp) +char *tag; +frdest_t *fdp; +{ + printf("%s %s%s", tag, fdp->fd_ifname, + (fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)"); +#ifdef USE_INET6 + if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) { + char ipv6addr[80]; + + inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr, + sizeof(fdp->fd_ip6)); + printf(":%s", ipv6addr); + } else +#endif + if (fdp->fd_ip.s_addr) + printf(":%s", inet_ntoa(fdp->fd_ip)); + putchar(' '); +} diff --git a/contrib/ipfilter/lib/printactivenat.c b/contrib/ipfilter/lib/printactivenat.c new file mode 100644 index 000000000000..3c56b14d3592 --- /dev/null +++ b/contrib/ipfilter/lib/printactivenat.c @@ -0,0 +1,85 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: printactivenat.c,v 1.3.2.4 2004/05/11 16:07:32 darrenr Exp"; +#endif + + +void printactivenat(nat, opts) +nat_t *nat; +int opts; +{ + + printf("%s", getnattype(nat->nat_ptr)); + + if (nat->nat_flags & SI_CLONE) + printf(" CLONE"); + + printf(" %-15s", inet_ntoa(nat->nat_inip)); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + printf(" %-5hu", ntohs(nat->nat_inport)); + + printf(" <- -> %-15s",inet_ntoa(nat->nat_outip)); + + if ((nat->nat_flags & IPN_TCPUDP) != 0) + printf(" %-5hu", ntohs(nat->nat_outport)); + + printf(" [%s", inet_ntoa(nat->nat_oip)); + if ((nat->nat_flags & IPN_TCPUDP) != 0) + printf(" %hu", ntohs(nat->nat_oport)); + printf("]"); + + if (opts & OPT_VERBOSE) { + printf("\n\tage %lu use %hu sumd %s/", + nat->nat_age, nat->nat_use, getsumd(nat->nat_sumd[0])); + printf("%s pr %u bkt %d/%d flags %x\n", + getsumd(nat->nat_sumd[1]), nat->nat_p, + nat->nat_hv[0], nat->nat_hv[1], nat->nat_flags); + printf("\tifp %s", getifname(nat->nat_ifps[0])); + printf(",%s ", getifname(nat->nat_ifps[1])); +#ifdef USE_QUAD_T + printf("bytes %qu/%qu pkts %qu/%qu", + (unsigned long long)nat->nat_bytes[0], + (unsigned long long)nat->nat_bytes[1], + (unsigned long long)nat->nat_pkts[0], + (unsigned long long)nat->nat_pkts[1]); +#else + printf("bytes %lu/%lu pkts %lu/%lu", nat->nat_bytes[0], + nat->nat_bytes[1], nat->nat_pkts[0], nat->nat_pkts[1]); +#endif + printf(" ipsumd %x", nat->nat_ipsumd); + } + + if (opts & OPT_DEBUG) { + printf("\n\tnat_next %p _pnext %p _hm %p\n", + nat->nat_next, nat->nat_pnext, nat->nat_hm); + printf("\t_hnext %p/%p _phnext %p/%p\n", + nat->nat_hnext[0], nat->nat_hnext[1], + nat->nat_phnext[0], nat->nat_phnext[1]); + printf("\t_data %p _me %p _state %p _aps %p\n", + nat->nat_data, nat->nat_me, nat->nat_state, nat->nat_aps); + printf("\tfr %p ptr %p ifps %p/%p sync %p\n", + nat->nat_fr, nat->nat_ptr, nat->nat_ifps[0], + nat->nat_ifps[1], nat->nat_sync); + printf("\ttqe:pnext %p next %p ifq %p parent %p/%p\n", + nat->nat_tqe.tqe_pnext, nat->nat_tqe.tqe_next, + nat->nat_tqe.tqe_ifq, nat->nat_tqe.tqe_parent, nat); + printf("\ttqe:die %ld touched %ld flags %x state %d/%d\n", + nat->nat_tqe.tqe_die, nat->nat_tqe.tqe_touched, + nat->nat_tqe.tqe_flags, nat->nat_tqe.tqe_state[0], + nat->nat_tqe.tqe_state[1]); + } + putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printaps.c b/contrib/ipfilter/lib/printaps.c new file mode 100644 index 000000000000..5c5c3ddef98a --- /dev/null +++ b/contrib/ipfilter/lib/printaps.c @@ -0,0 +1,112 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" +#include "kmem.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: printaps.c,v 1.4 2004/01/08 13:34:32 darrenr Exp"; +#endif + + +void printaps(aps, opts) +ap_session_t *aps; +int opts; +{ + ipsec_pxy_t ipsec; + ap_session_t ap; + ftpinfo_t ftp; + aproxy_t apr; + raudio_t ra; + + if (kmemcpy((char *)&ap, (long)aps, sizeof(ap))) + return; + if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr))) + return; + printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label, + apr.apr_p, apr.apr_ref, apr.apr_flags); + printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags); +#ifdef USE_QUAD_T + printf("%qu pkts %qu", (unsigned long long)ap.aps_bytes, + (unsigned long long)ap.aps_pkts); +#else + printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts); +#endif + printf(" data %s size %d\n", ap.aps_data ? "YES" : "NO", ap.aps_psiz); + if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { + printf("\t\tstate[%u,%u], sel[%d,%d]\n", + ap.aps_state[0], ap.aps_state[1], + ap.aps_sel[0], ap.aps_sel[1]); +#if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \ + (__FreeBSD_version >= 300000) || defined(OpenBSD) + printf("\t\tseq: off %hd/%hd min %x/%x\n", + ap.aps_seqoff[0], ap.aps_seqoff[1], + ap.aps_seqmin[0], ap.aps_seqmin[1]); + printf("\t\tack: off %hd/%hd min %x/%x\n", + ap.aps_ackoff[0], ap.aps_ackoff[1], + ap.aps_ackmin[0], ap.aps_ackmin[1]); +#else + printf("\t\tseq: off %hd/%hd min %lx/%lx\n", + ap.aps_seqoff[0], ap.aps_seqoff[1], + ap.aps_seqmin[0], ap.aps_seqmin[1]); + printf("\t\tack: off %hd/%hd min %lx/%lx\n", + ap.aps_ackoff[0], ap.aps_ackoff[1], + ap.aps_ackmin[0], ap.aps_ackmin[1]); +#endif + } + + if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) { + if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra))) + return; + printf("\tReal Audio Proxy:\n"); + printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", + ra.rap_seenpna, ra.rap_version, ra.rap_eos); + printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf); + printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n", + ra.rap_plport, ra.rap_prport, ra.rap_srport); + } else if (!strcmp(apr.apr_label, "ftp") && + (ap.aps_psiz == sizeof(ftp))) { + if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp))) + return; + printf("\tFTP Proxy:\n"); + printf("\t\tpassok: %d\n", ftp.ftp_passok); + ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0'; + ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0'; + printf("\tClient:\n"); + printf("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", + ftp.ftp_side[0].ftps_seq[0], + ftp.ftp_side[0].ftps_seq[1], + ftp.ftp_side[0].ftps_len, ftp.ftp_side[0].ftps_junk, + ftp.ftp_side[0].ftps_cmds); + printf("\t\tbuf ["); + printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1); + printf("]\n\tServer:\n"); + printf("\t\tseq %x (ack %x) len %d junk %d cmds %d\n", + ftp.ftp_side[1].ftps_seq[0], + ftp.ftp_side[1].ftps_seq[1], + ftp.ftp_side[1].ftps_len, ftp.ftp_side[1].ftps_junk, + ftp.ftp_side[1].ftps_cmds); + printf("\t\tbuf ["); + printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1); + printf("]\n"); + } else if (!strcmp(apr.apr_label, "ipsec") && + (ap.aps_psiz == sizeof(ipsec))) { + if (kmemcpy((char *)&ipsec, (long)ap.aps_data, sizeof(ipsec))) + return; + printf("\tIPSec Proxy:\n"); + printf("\t\tICookie %08x%08x RCookie %08x%08x %s\n", + (u_int)ntohl(ipsec.ipsc_icookie[0]), + (u_int)ntohl(ipsec.ipsc_icookie[1]), + (u_int)ntohl(ipsec.ipsc_rcookie[0]), + (u_int)ntohl(ipsec.ipsc_rcookie[1]), + ipsec.ipsc_rckset ? "(Set)" : "(Not set)"); + } +} diff --git a/contrib/ipfilter/lib/printbuf.c b/contrib/ipfilter/lib/printbuf.c new file mode 100644 index 000000000000..f2b7faaeb510 --- /dev/null +++ b/contrib/ipfilter/lib/printbuf.c @@ -0,0 +1,32 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printbuf.c,v 1.5.4.1 2004/12/09 19:41:22 darrenr Exp + */ + +#include + +#include "ipf.h" + + +void printbuf(buf, len, zend) +char *buf; +int len, zend; +{ + char *s, c; + int i; + + for (s = buf, i = len; i; i--) { + c = *s++; + if (ISPRINT(c)) + putchar(c); + else + printf("\\%03o", c); + if ((c == '\0') && zend) + break; + } +} diff --git a/contrib/ipfilter/lib/printfr.c b/contrib/ipfilter/lib/printfr.c new file mode 100644 index 000000000000..f0f5a0e0c1dd --- /dev/null +++ b/contrib/ipfilter/lib/printfr.c @@ -0,0 +1,445 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printfr.c,v 1.43.2.10 2005/03/16 15:38:13 darrenr Exp + */ + +#include "ipf.h" + +static void printaddr(int, int, char *, u_32_t *, u_32_t *); + +static void printaddr(v, type, ifname, addr, mask) +int v, type; +char *ifname; +u_32_t *addr, *mask; +{ + char *suffix; + + switch (type) + { + case FRI_BROADCAST : + suffix = "/bcast"; + break; + + case FRI_DYNAMIC : + printf("%s", ifname); + printmask(mask); + suffix = NULL; + break; + + case FRI_NETWORK : + suffix = "/net"; + break; + + case FRI_NETMASKED : + suffix = "/netmasked"; + break; + + case FRI_PEERADDR : + suffix = "/peer"; + break; + + case FRI_LOOKUP : + suffix = NULL; + printlookup((i6addr_t *)addr, (i6addr_t *)mask); + break; + + case FRI_NORMAL : + printhostmask(v, addr, mask); + suffix = NULL; + break; + default : + printf("<%d>", type); + printmask(mask); + suffix = NULL; + break; + } + + if (suffix != NULL) { + printf("%s/%s", ifname, suffix); + } +} + + +void printlookup(addr, mask) +i6addr_t *addr, *mask; +{ + switch (addr->iplookuptype) + { + case IPLT_POOL : + printf("pool/"); + break; + case IPLT_HASH : + printf("hash/"); + break; + default : + printf("lookup(%x)=", addr->iplookuptype); + break; + } + + printf("%u", addr->iplookupnum); + if (mask->iplookupptr == NULL) + printf("(!)"); +} + + +/* + * print the filter structure in a useful way + */ +void printfr(fp, iocfunc) +struct frentry *fp; +ioctlfunc_t iocfunc; +{ + struct protoent *p; + u_short sec[2]; + u_32_t type; + u_char *t; + char *s; + int pr; + + pr = -2; + type = fp->fr_type & ~FR_T_BUILTIN; + + if ((fp->fr_type & FR_T_BUILTIN) != 0) + printf("# Builtin: "); + + if (fp->fr_type == FR_T_CALLFUNC) { + ; + } else if (fp->fr_func != NULL) { + printf("call"); + if ((fp->fr_flags & FR_CALLNOW) != 0) + printf(" now"); + s = kvatoname(fp->fr_func, iocfunc); + printf(" %s/%u", s ? s : "?", fp->fr_arg); + } else if (FR_ISPASS(fp->fr_flags)) + printf("pass"); + else if (FR_ISBLOCK(fp->fr_flags)) { + printf("block"); + if (fp->fr_flags & FR_RETICMP) { + if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) + printf(" return-icmp-as-dest"); + else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) + printf(" return-icmp"); + if (fp->fr_icode) { + if (fp->fr_icode <= MAX_ICMPCODE) + printf("(%s)", + icmpcodes[(int)fp->fr_icode]); + else + printf("(%d)", fp->fr_icode); + } + } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) + printf(" return-rst"); + } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { + printlog(fp); + } else if (FR_ISACCOUNT(fp->fr_flags)) + printf("count"); + else if (FR_ISAUTH(fp->fr_flags)) + printf("auth"); + else if (FR_ISPREAUTH(fp->fr_flags)) + printf("preauth"); + else if (FR_ISNOMATCH(fp->fr_flags)) + printf("nomatch"); + else if (FR_ISSKIP(fp->fr_flags)) + printf("skip %u", fp->fr_arg); + else { + printf("%x", fp->fr_flags); + } + + if (fp->fr_flags & FR_OUTQUE) + printf(" out "); + else + printf(" in "); + + if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || + ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { + printlog(fp); + putchar(' '); + } + + if (fp->fr_flags & FR_QUICK) + printf("quick "); + + if (*fp->fr_ifname) { + printifname("on ", fp->fr_ifname, fp->fr_ifa); + if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*")) + printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]); + putchar(' '); + } + + if (*fp->fr_dif.fd_ifname || (fp->fr_flags & FR_DUP)) + print_toif("dup-to", &fp->fr_dif); + if (*fp->fr_tif.fd_ifname) + print_toif("to", &fp->fr_tif); + if (*fp->fr_rif.fd_ifname) + print_toif("reply-to", &fp->fr_rif); + if (fp->fr_flags & FR_FASTROUTE) + printf("fastroute "); + + if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) || + (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) { + if (fp->fr_flags & FR_OUTQUE) + printf("in-via "); + else + printf("out-via "); + + if (*fp->fr_ifnames[2]) { + printifname("", fp->fr_ifnames[2], + fp->fr_ifas[2]); + putchar(' '); + + if (*fp->fr_ifnames[3]) { + printifname(",", fp->fr_ifnames[3], + fp->fr_ifas[3]); + } + } + } + + if (type == FR_T_IPF) { + if (fp->fr_mip.fi_tos) + printf("tos %#x ", fp->fr_tos); + if (fp->fr_mip.fi_ttl) + printf("ttl %d ", fp->fr_ttl); + if (fp->fr_flx & FI_TCPUDP) { + printf("proto tcp/udp "); + pr = -1; + } else if (fp->fr_mip.fi_p) { + pr = fp->fr_ip.fi_p; + if ((p = getprotobynumber(fp->fr_proto))) + printf("proto %s ", p->p_name); + else + printf("proto %d ", fp->fr_proto); + } + } + + if (type == FR_T_NONE) { + printf("all"); + } else if (type == FR_T_IPF) { + printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); + printaddr(fp->fr_v, fp->fr_satype, fp->fr_ifname, + &fp->fr_src.s_addr, &fp->fr_smsk.s_addr); + if (fp->fr_scmp) + printportcmp(pr, &fp->fr_tuc.ftu_src); + + printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); + printaddr(fp->fr_v, fp->fr_datype, fp->fr_ifname, + &fp->fr_dst.s_addr, &fp->fr_dmsk.s_addr); + if (fp->fr_dcmp) + printportcmp(pr, &fp->fr_tuc.ftu_dst); + + if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) { + int type = fp->fr_icmp, code; + + type = ntohs(fp->fr_icmp); + code = type & 0xff; + type /= 256; + if (type < (sizeof(icmptypes) / sizeof(char *) - 1) && + icmptypes[type]) + printf(" icmp-type %s", icmptypes[type]); + else + printf(" icmp-type %d", type); + if (ntohs(fp->fr_icmpm) & 0xff) + printf(" code %d", code); + } + if ((fp->fr_proto == IPPROTO_TCP) && + (fp->fr_tcpf || fp->fr_tcpfm)) { + printf(" flags "); + if (fp->fr_tcpf & ~TCPF_ALL) + printf("0x%x", fp->fr_tcpf); + else + for (s = flagset, t = flags; *s; s++, t++) + if (fp->fr_tcpf & *t) + (void)putchar(*s); + if (fp->fr_tcpfm) { + (void)putchar('/'); + if (fp->fr_tcpfm & ~TCPF_ALL) + printf("0x%x", fp->fr_tcpfm); + else + for (s = flagset, t = flags; *s; + s++, t++) + if (fp->fr_tcpfm & *t) + (void)putchar(*s); + } + } + } else if (type == FR_T_BPFOPC) { + fakebpf_t *fb; + int i; + + printf("bpf-v%d { \"", fp->fr_v); + i = fp->fr_dsize / sizeof(*fb); + + for (fb = fp->fr_data, s = ""; i; i--, fb++, s = " ") + printf("%s%#x %#x %#x %#x", s, fb->fb_c, fb->fb_t, + fb->fb_f, fb->fb_k); + + printf("\" }"); + } else if (type == FR_T_COMPIPF) { + ; + } else if (type == FR_T_CALLFUNC) { + printf("call function at %p", fp->fr_data); + } else { + printf("[unknown filter type %#x]", fp->fr_type); + } + + if ((type == FR_T_IPF) && + ((fp->fr_flx & FI_WITH) || (fp->fr_mflx & FI_WITH) || + fp->fr_optbits || fp->fr_optmask || + fp->fr_secbits || fp->fr_secmask)) { + char *comma = " "; + + printf(" with"); + if (fp->fr_optbits || fp->fr_optmask || + fp->fr_secbits || fp->fr_secmask) { + sec[0] = fp->fr_secmask; + sec[1] = fp->fr_secbits; + if (fp->fr_v == 4) + optprint(sec, fp->fr_optmask, fp->fr_optbits); +#ifdef USE_INET6 + else + optprintv6(sec, fp->fr_optmask, + fp->fr_optbits); +#endif + } else if (fp->fr_mflx & FI_OPTIONS) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_OPTIONS)) + printf("not "); + printf("ipopts"); + comma = ","; + } + if (fp->fr_mflx & FI_SHORT) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_SHORT)) + printf("not "); + printf("short"); + comma = ","; + } + if (fp->fr_mflx & FI_FRAG) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_FRAG)) + printf("not "); + printf("frag"); + comma = ","; + } + if (fp->fr_mflx & FI_FRAGBODY) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_FRAGBODY)) + printf("not "); + printf("frag-body"); + comma = ","; + } + if (fp->fr_mflx & FI_NATED) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_NATED)) + printf("not "); + printf("nat"); + comma = ","; + } + if (fp->fr_mflx & FI_LOWTTL) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_LOWTTL)) + printf("not "); + printf("lowttl"); + comma = ","; + } + if (fp->fr_mflx & FI_BAD) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_BAD)) + printf("not "); + printf("bad"); + comma = ","; + } + if (fp->fr_mflx & FI_BADSRC) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_BADSRC)) + printf("not "); + printf("bad-src"); + comma = ","; + } + if (fp->fr_mflx & FI_BADNAT) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_BADNAT)) + printf("not "); + printf("bad-nat"); + comma = ","; + } + if (fp->fr_mflx & FI_OOW) { + fputs(comma, stdout); + if (!(fp->fr_flx & FI_OOW)) + printf("not "); + printf("oow"); + } + } + + if (fp->fr_flags & FR_KEEPSTATE) { + printf(" keep state"); + if ((fp->fr_flags & (FR_STSTRICT|FR_NEWISN|FR_NOICMPERR|FR_STATESYNC)) || + (fp->fr_statemax != 0) || (fp->fr_age[0] != 0)) { + char *comma = ""; + printf(" ("); + if (fp->fr_statemax != 0) { + printf("limit %u", fp->fr_statemax); + comma = ","; + } + if (fp->fr_flags & FR_STSTRICT) { + printf("%sstrict", comma); + comma = ","; + } + if (fp->fr_flags & FR_NEWISN) { + printf("%snewisn", comma); + comma = ","; + } + if (fp->fr_flags & FR_NOICMPERR) { + printf("%sno-icmp-err", comma); + comma = ","; + } + if (fp->fr_flags & FR_STATESYNC) { + printf("%ssync", comma); + comma = ","; + } + if (fp->fr_age[0] || fp->fr_age[1]) + printf("%sage %d/%d", comma, fp->fr_age[0], + fp->fr_age[1]); + printf(")"); + } + } + if (fp->fr_flags & FR_KEEPFRAG) { + printf(" keep frags"); + if (fp->fr_flags & (FR_FRSTRICT)) { + printf(" ("); + if (fp->fr_flags & FR_FRSTRICT) + printf(" strict"); + printf(" )"); + + } + } + if (fp->fr_isc != (struct ipscan *)-1) { + if (fp->fr_isctag[0]) + printf(" scan %s", fp->fr_isctag); + else + printf(" scan *"); + } + if (*fp->fr_grhead != '\0') + printf(" head %s", fp->fr_grhead); + if (*fp->fr_group != '\0') + printf(" group %s", fp->fr_group); + if (fp->fr_logtag != FR_NOLOGTAG || *fp->fr_nattag.ipt_tag) { + char *s = ""; + + printf(" set-tag("); + if (fp->fr_logtag != FR_NOLOGTAG) { + printf("log=%u", fp->fr_logtag); + s = ", "; + } + if (*fp->fr_nattag.ipt_tag) { + printf("%snat=%-.*s", s, IPFTAG_LEN, + fp->fr_nattag.ipt_tag); + } + printf(")"); + } + if (fp->fr_pps) + printf(" pps %d", fp->fr_pps); + (void)putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printfraginfo.c b/contrib/ipfilter/lib/printfraginfo.c new file mode 100644 index 000000000000..b521c8315eff --- /dev/null +++ b/contrib/ipfilter/lib/printfraginfo.c @@ -0,0 +1,29 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2004 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printfraginfo.c,v 1.1.2.2 2004/03/23 15:15:45 darrenr Exp + */ +#include "ipf.h" +#include "kmem.h" + +void printfraginfo(prefix, ifr) +char *prefix; +struct ipfr *ifr; +{ + frentry_t fr; + + fr.fr_flags = 0xffffffff; + + printf("%s%s -> ", prefix, hostname(4, &ifr->ipfr_src)); + if (kmemcpy((char *)&fr, (u_long)ifr->ipfr_rule, + sizeof(fr)) == -1) + return; + printf("%s id %d ttl %d pr %d seen0 %d ifp %p tos %#02x = %#x\n", + hostname(4, &ifr->ipfr_dst), ifr->ipfr_id, ifr->ipfr_seen0, + ifr->ipfr_ttl, ifr->ipfr_p, ifr->ipfr_ifp, ifr->ipfr_tos, + fr.fr_flags); +} diff --git a/contrib/ipfilter/lib/printhash.c b/contrib/ipfilter/lib/printhash.c new file mode 100644 index 000000000000..80157bb1d27f --- /dev/null +++ b/contrib/ipfilter/lib/printhash.c @@ -0,0 +1,144 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + + +iphtable_t *printhash(hp, copyfunc, name, opts) +iphtable_t *hp; +copyfunc_t copyfunc; +char *name; +int opts; +{ + iphtent_t *ipep, **table; + iphtable_t iph; + int i, printed; + size_t sz; + + if ((*copyfunc)((char *)hp, (char *)&iph, sizeof(iph))) + return NULL; + + if ((name != NULL) && strncmp(name, iph.iph_name, FR_GROUPLEN)) + return iph.iph_next; + + if ((opts & OPT_DEBUG) == 0) { + if ((iph.iph_type & IPHASH_ANON) == IPHASH_ANON) + PRINTF("# 'anonymous' table\n"); + switch (iph.iph_type & ~IPHASH_ANON) + { + case IPHASH_LOOKUP : + PRINTF("table"); + break; + case IPHASH_GROUPMAP : + PRINTF("group-map"); + if (iph.iph_flags & FR_INQUE) + PRINTF(" in"); + else if (iph.iph_flags & FR_OUTQUE) + PRINTF(" out"); + else + PRINTF(" ???"); + break; + default : + PRINTF("%#x", iph.iph_type); + break; + } + PRINTF(" role = "); + } else { + PRINTF("Hash Table Number: %s", iph.iph_name); + if ((iph.iph_type & IPHASH_ANON) == IPHASH_ANON) + PRINTF("(anon)"); + putchar(' '); + PRINTF("Role: "); + } + + switch (iph.iph_unit) + { + case IPL_LOGNAT : + PRINTF("nat"); + break; + case IPL_LOGIPF : + PRINTF("ipf"); + break; + case IPL_LOGAUTH : + PRINTF("auth"); + break; + case IPL_LOGCOUNT : + PRINTF("count"); + break; + default : + PRINTF("#%d", iph.iph_unit); + break; + } + + if ((opts & OPT_DEBUG) == 0) { + if ((iph.iph_type & ~IPHASH_ANON) == IPHASH_LOOKUP) + PRINTF(" type = hash"); + PRINTF(" number = %s size = %lu", + iph.iph_name, (u_long)iph.iph_size); + if (iph.iph_seed != 0) + PRINTF(" seed = %lu", iph.iph_seed); + putchar('\n'); + } else { + PRINTF(" Type: "); + switch (iph.iph_type & ~IPHASH_ANON) + { + case IPHASH_LOOKUP : + PRINTF("lookup"); + break; + case IPHASH_GROUPMAP : + PRINTF("groupmap Group. %s", iph.iph_name); + break; + default : + break; + } + + putchar('\n'); + PRINTF("\t\tSize: %lu\tSeed: %lu", + (u_long)iph.iph_size, iph.iph_seed); + PRINTF("\tRef. Count: %d\tMasks: %#x\n", iph.iph_ref, + iph.iph_masks); + } + + if ((opts & OPT_DEBUG) != 0) { + struct in_addr m; + + for (i = 0; i < 32; i++) { + if ((1 << i) & iph.iph_masks) { + ntomask(4, i, &m.s_addr); + PRINTF("\t\tMask: %s\n", inet_ntoa(m)); + } + } + } + + if ((opts & OPT_DEBUG) == 0) + PRINTF("\t{"); + + sz = iph.iph_size * sizeof(*table); + table = malloc(sz); + if ((*copyfunc)((char *)iph.iph_table, (char *)table, sz)) + return NULL; + + for (i = 0, printed = 0; i < iph.iph_size; i++) { + for (ipep = table[i]; ipep != NULL; ) { + ipep = printhashnode(&iph, ipep, copyfunc, opts); + printed++; + } + } + if (printed == 0) + putchar(';'); + + free(table); + + if ((opts & OPT_DEBUG) == 0) + PRINTF(" };\n"); + + return iph.iph_next; +} diff --git a/contrib/ipfilter/lib/printhashnode.c b/contrib/ipfilter/lib/printhashnode.c new file mode 100644 index 000000000000..39255e70d127 --- /dev/null +++ b/contrib/ipfilter/lib/printhashnode.c @@ -0,0 +1,52 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +iphtent_t *printhashnode(iph, ipep, copyfunc, opts) +iphtable_t *iph; +iphtent_t *ipep; +copyfunc_t copyfunc; +int opts; +{ + iphtent_t ipe; + + if ((*copyfunc)(ipep, &ipe, sizeof(ipe))) + return NULL; + + ipe.ipe_addr.in4_addr = htonl(ipe.ipe_addr.in4_addr); + ipe.ipe_mask.in4_addr = htonl(ipe.ipe_mask.in4_addr); + + if ((opts & OPT_DEBUG) != 0) { + PRINTF("\tAddress: %s", + inet_ntoa(ipe.ipe_addr.in4)); + printmask((u_32_t *)&ipe.ipe_mask.in4_addr); + PRINTF("\tRef. Count: %d\tGroup: %s\n", ipe.ipe_ref, + ipe.ipe_group); + } else { + putchar(' '); + printip((u_32_t *)&ipe.ipe_addr.in4_addr); + printmask((u_32_t *)&ipe.ipe_mask.in4_addr); + if (ipe.ipe_value != 0) { + switch (iph->iph_type & ~IPHASH_ANON) + { + case IPHASH_GROUPMAP : + if (strncmp(ipe.ipe_group, iph->iph_name, + FR_GROUPLEN)) + PRINTF(", group = %s", ipe.ipe_group); + break; + } + } + putchar(';'); + } + ipep = ipe.ipe_next; + return ipep; +} diff --git a/contrib/ipfilter/lib/printhostmap.c b/contrib/ipfilter/lib/printhostmap.c new file mode 100644 index 000000000000..bdb670254095 --- /dev/null +++ b/contrib/ipfilter/lib/printhostmap.c @@ -0,0 +1,13 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +void printhostmap(hmp, hv) +hostmap_t *hmp; +u_int hv; +{ + printf("%s,", inet_ntoa(hmp->hm_srcip)); + printf("%s -> ", inet_ntoa(hmp->hm_dstip)); + printf("%s ", inet_ntoa(hmp->hm_mapip)); + printf("(use = %d hv = %u)\n", hmp->hm_ref, hv); +} diff --git a/contrib/ipfilter/lib/printhostmask.c b/contrib/ipfilter/lib/printhostmask.c new file mode 100644 index 000000000000..c34bc43723a2 --- /dev/null +++ b/contrib/ipfilter/lib/printhostmask.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printhostmask.c,v 1.8 2002/04/11 15:01:19 darrenr Exp + */ + +#include "ipf.h" + + +void printhostmask(v, addr, mask) +int v; +u_32_t *addr, *mask; +{ +#ifdef USE_INET6 + char ipbuf[64]; +#else + struct in_addr ipa; +#endif + + if (!*addr && !*mask) + printf("any"); + else { +#ifdef USE_INET6 + void *ptr = addr; + int af; + + if (v == 4) { + ptr = addr; + af = AF_INET; + } else if (v == 6) { + ptr = addr; + af = AF_INET6; + } else + af = 0; + printf("%s", inet_ntop(af, ptr, ipbuf, sizeof(ipbuf))); +#else + ipa.s_addr = *addr; + printf("%s", inet_ntoa(ipa)); +#endif + printmask(mask); + } +} diff --git a/contrib/ipfilter/lib/printifname.c b/contrib/ipfilter/lib/printifname.c new file mode 100644 index 000000000000..53a7fd77fa01 --- /dev/null +++ b/contrib/ipfilter/lib/printifname.c @@ -0,0 +1,20 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printifname.c,v 1.2 2002/01/28 06:50:47 darrenr Exp + */ + +#include "ipf.h" + +void printifname(format, name, ifp) +char *format, *name; +void *ifp; +{ + printf("%s%s", format, name); + if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*")) + printf("(!)"); +} diff --git a/contrib/ipfilter/lib/printip.c b/contrib/ipfilter/lib/printip.c new file mode 100644 index 000000000000..1a04f1d41846 --- /dev/null +++ b/contrib/ipfilter/lib/printip.c @@ -0,0 +1,24 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printip.c,v 1.3 2002/07/13 12:10:27 darrenr Exp + */ + +#include "ipf.h" + + +void printip(addr) +u_32_t *addr; +{ + struct in_addr ipa; + + ipa.s_addr = *addr; + if (ntohl(ipa.s_addr) < 256) + printf("%lu", (u_long)ntohl(ipa.s_addr)); + else + printf("%s", inet_ntoa(ipa)); +} diff --git a/contrib/ipfilter/lib/printlog.c b/contrib/ipfilter/lib/printlog.c new file mode 100644 index 000000000000..d14add42945f --- /dev/null +++ b/contrib/ipfilter/lib/printlog.c @@ -0,0 +1,44 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printlog.c,v 1.6 2002/01/28 06:50:47 darrenr Exp + */ + +#include "ipf.h" + +#include + + +void printlog(fp) +frentry_t *fp; +{ + char *s, *u; + + printf("log"); + if (fp->fr_flags & FR_LOGBODY) + printf(" body"); + if (fp->fr_flags & FR_LOGFIRST) + printf(" first"); + if (fp->fr_flags & FR_LOGORBLOCK) + printf(" or-block"); + if (fp->fr_loglevel != 0xffff) { + printf(" level "); + if (fp->fr_loglevel & LOG_FACMASK) { + s = fac_toname(fp->fr_loglevel); + if (s == NULL) + s = "!!!"; + } else + s = ""; + u = pri_toname(fp->fr_loglevel); + if (u == NULL) + u = "!!!"; + if (*s) + printf("%s.%s", s, u); + else + printf("%s", u); + } +} diff --git a/contrib/ipfilter/lib/printmask.c b/contrib/ipfilter/lib/printmask.c new file mode 100644 index 000000000000..d3d9a6f1e5f8 --- /dev/null +++ b/contrib/ipfilter/lib/printmask.c @@ -0,0 +1,30 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printmask.c,v 1.5 2002/06/15 04:48:33 darrenr Exp + */ + +#include "ipf.h" + + +void printmask(mask) +u_32_t *mask; +{ + struct in_addr ipa; + int ones; + +#ifdef USE_INET6 + if (use_inet6) + printf("/%d", count6bits(mask)); + else +#endif + if ((ones = count4bits(*mask)) == -1) { + ipa.s_addr = *mask; + printf("/%s", inet_ntoa(ipa)); + } else + printf("/%d", ones); +} diff --git a/contrib/ipfilter/lib/printnat.c b/contrib/ipfilter/lib/printnat.c new file mode 100644 index 000000000000..15a688606a85 --- /dev/null +++ b/contrib/ipfilter/lib/printnat.c @@ -0,0 +1,247 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ + +#include "ipf.h" +#include "kmem.h" + + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: printnat.c,v 1.22.2.8 2005/01/12 03:39:04 darrenr Exp"; +#endif + +static void printproto __P((ipnat_t *, struct protoent *)); + +/* + * Print out a NAT rule + */ +void printnat(np, opts) +ipnat_t *np; +int opts; +{ + struct protoent *pr; + int bits; + + pr = getprotobynumber(np->in_p); + + switch (np->in_redir) + { + case NAT_REDIRECT : + printf("rdr"); + break; + case NAT_MAP : + printf("map"); + break; + case NAT_MAPBLK : + printf("map-block"); + break; + case NAT_BIMAP : + printf("bimap"); + break; + default : + fprintf(stderr, "unknown value for in_redir: %#x\n", + np->in_redir); + break; + } + + printf(" %s", np->in_ifnames[0]); + if ((np->in_ifnames[1][0] != '\0') && + (strncmp(np->in_ifnames[0], np->in_ifnames[1], LIFNAMSIZ) != 0)) { + printf(",%s ", np->in_ifnames[1]); + } + putchar(' '); + + if (np->in_flags & IPN_FILTER) { + if (np->in_flags & IPN_NOTSRC) + printf("! "); + printf("from "); + if (np->in_redir == NAT_REDIRECT) { + printhostmask(4, (u_32_t *)&np->in_srcip, + (u_32_t *)&np->in_srcmsk); + } else { + printhostmask(4, (u_32_t *)&np->in_inip, + (u_32_t *)&np->in_inmsk); + } + if (np->in_scmp) + printportcmp(np->in_p, &np->in_tuc.ftu_src); + + if (np->in_flags & IPN_NOTDST) + printf(" !"); + printf(" to "); + if (np->in_redir == NAT_REDIRECT) { + printhostmask(4, (u_32_t *)&np->in_outip, + (u_32_t *)&np->in_outmsk); + } else { + printhostmask(4, (u_32_t *)&np->in_srcip, + (u_32_t *)&np->in_srcmsk); + } + if (np->in_dcmp) + printportcmp(np->in_p, &np->in_tuc.ftu_dst); + } + + if (np->in_redir == NAT_REDIRECT) { + if (!(np->in_flags & IPN_FILTER)) { + printf("%s", inet_ntoa(np->in_out[0].in4)); + bits = count4bits(np->in_outmsk); + if (bits != -1) + printf("/%d", bits); + else + printf("/%s", inet_ntoa(np->in_out[1].in4)); + if (np->in_flags & IPN_TCPUDP) { + printf(" port %d", ntohs(np->in_pmin)); + if (np->in_pmax != np->in_pmin) + printf("-%d", ntohs(np->in_pmax)); + } + } + printf(" -> %s", inet_ntoa(np->in_in[0].in4)); + if (np->in_flags & IPN_SPLIT) + printf(",%s", inet_ntoa(np->in_in[1].in4)); + if (np->in_flags & IPN_TCPUDP) { + if ((np->in_flags & IPN_FIXEDDPORT) != 0) + printf(" port = %d", ntohs(np->in_pnext)); + else + printf(" port %d", ntohs(np->in_pnext)); + } + printproto(np, pr); + if (np->in_flags & IPN_ROUNDR) + printf(" round-robin"); + if (np->in_flags & IPN_FRAG) + printf(" frag"); + if (np->in_age[0] != 0 || np->in_age[1] != 0) { + printf(" age %d/%d", np->in_age[0], np->in_age[1]); + } + if (np->in_flags & IPN_STICKY) + printf(" sticky"); + if (np->in_mssclamp != 0) + printf(" mssclamp %d", np->in_mssclamp); + if (*np->in_plabel != '\0') + printf(" proxy %.*s", (int)sizeof(np->in_plabel), + np->in_plabel); + if (np->in_tag.ipt_tag[0] != '\0') + printf(" tag %-.*s", IPFTAG_LEN, np->in_tag.ipt_tag); + printf("\n"); + if (opts & OPT_DEBUG) + printf("\tpmax %u\n", np->in_pmax); + } else { + if (!(np->in_flags & IPN_FILTER)) { + printf("%s/", inet_ntoa(np->in_in[0].in4)); + bits = count4bits(np->in_inmsk); + if (bits != -1) + printf("%d", bits); + else + printf("%s", inet_ntoa(np->in_in[1].in4)); + } + printf(" -> "); + if (np->in_flags & IPN_IPRANGE) { + printf("range %s-", inet_ntoa(np->in_out[0].in4)); + printf("%s", inet_ntoa(np->in_out[1].in4)); + } else { + printf("%s/", inet_ntoa(np->in_out[0].in4)); + bits = count4bits(np->in_outmsk); + if (bits != -1) + printf("%d", bits); + else + printf("%s", inet_ntoa(np->in_out[1].in4)); + } + if (*np->in_plabel != '\0') { + printf(" proxy port "); + if (np->in_dcmp != 0) + np->in_dport = htons(np->in_dport); + if (np->in_dport != 0) { + char *s; + + s = portname(np->in_p, ntohs(np->in_dport)); + if (s != NULL) + fputs(s, stdout); + else + fputs("???", stdout); + } + printf(" %.*s/", (int)sizeof(np->in_plabel), + np->in_plabel); + if (pr != NULL) + fputs(pr->p_name, stdout); + else + printf("%d", np->in_p); + } else if (np->in_redir == NAT_MAPBLK) { + if ((np->in_pmin == 0) && + (np->in_flags & IPN_AUTOPORTMAP)) + printf(" ports auto"); + else + printf(" ports %d", np->in_pmin); + if (opts & OPT_DEBUG) + printf("\n\tip modulous %d", np->in_pmax); + } else if (np->in_pmin || np->in_pmax) { + if (np->in_flags & IPN_ICMPQUERY) { + printf(" icmpidmap"); + } else { + printf(" portmap"); + } + printproto(np, pr); + if (np->in_flags & IPN_AUTOPORTMAP) { + printf(" auto"); + if (opts & OPT_DEBUG) + printf(" [%d:%d %d %d]", + ntohs(np->in_pmin), + ntohs(np->in_pmax), + np->in_ippip, np->in_ppip); + } else { + printf(" %d:%d", ntohs(np->in_pmin), + ntohs(np->in_pmax)); + } + } else if (np->in_flags & IPN_TCPUDP || np->in_p) + printproto(np, pr); + + if (np->in_flags & IPN_FRAG) + printf(" frag"); + if (np->in_age[0] != 0 || np->in_age[1] != 0) { + printf(" age %d/%d", np->in_age[0], np->in_age[1]); + } + if (np->in_mssclamp != 0) + printf(" mssclamp %d", np->in_mssclamp); + if (np->in_tag.ipt_tag[0] != '\0') + printf(" tag %s", np->in_tag.ipt_tag); + printf("\n"); + if (opts & OPT_DEBUG) { + struct in_addr nip; + + nip.s_addr = htonl(np->in_nextip.s_addr); + + printf("\tnextip %s pnext %d\n", + inet_ntoa(nip), np->in_pnext); + } + } + + if (opts & OPT_DEBUG) { + printf("\tspace %lu use %u hits %lu flags %#x proto %d hv %d\n", + np->in_space, np->in_use, np->in_hits, + np->in_flags, np->in_p, np->in_hv); + printf("\tifp[0] %p ifp[1] %p apr %p\n", + np->in_ifps[0], np->in_ifps[1], np->in_apr); + printf("\ttqehead %p/%p comment %p\n", + np->in_tqehead[0], np->in_tqehead[1], np->in_comment); + } +} + +static void printproto(np, pr) +ipnat_t *np; +struct protoent *pr; +{ + if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) + printf(" tcp/udp"); + else if (np->in_flags & IPN_TCP) + printf(" tcp"); + else if (np->in_flags & IPN_UDP) + printf(" udp"); + else if (np->in_flags & IPN_ICMPQUERY) + printf(" icmp"); + else if (pr != NULL) + printf(" %s", pr->p_name); + else + printf(" %d", np->in_p); +} diff --git a/contrib/ipfilter/lib/printpacket.c b/contrib/ipfilter/lib/printpacket.c new file mode 100644 index 000000000000..58460bec2cc3 --- /dev/null +++ b/contrib/ipfilter/lib/printpacket.c @@ -0,0 +1,89 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printpacket.c,v 1.12.4.1 2005/02/21 05:09:24 darrenr Exp + */ + +#include "ipf.h" + +#ifndef IP_OFFMASK +# define IP_OFFMASK 0x3fff +#endif + + +void printpacket(ip) +struct ip *ip; +{ + struct tcphdr *tcp; + u_short len; + u_short off; + + if (IP_V(ip) == 6) { + off = 0; + len = ntohs(((u_short *)ip)[2]) + 40; + } else { + off = ntohs(ip->ip_off); + len = ntohs(ip->ip_len); + } + + if ((opts & OPT_HEX) == OPT_HEX) { + u_char *s; + int i; + + for (s = (u_char *)ip, i = 0; i < len; i++) { + printf("%02x", *s++ & 0xff); + if (len - i > 1) { + i++; + printf("%02x", *s++ & 0xff); + } + putchar(' '); + } + putchar('\n'); + return; + } + + if (IP_V(ip) == 6) { + printpacket6(ip); + return; + } + + tcp = (struct tcphdr *)((char *)ip + (IP_HL(ip) << 2)); + printf("ip %d(%d) %d", ntohs(ip->ip_len), IP_HL(ip) << 2, ip->ip_p); + if (off & IP_OFFMASK) + printf(" @%d", off << 3); + printf(" %s", inet_ntoa(ip->ip_src)); + if (!(off & IP_OFFMASK)) + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) + printf(",%d", ntohs(tcp->th_sport)); + printf(" > "); + printf("%s", inet_ntoa(ip->ip_dst)); + if (!(off & IP_OFFMASK)) { + if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) + printf(",%d", ntohs(tcp->th_dport)); + if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) { + putchar(' '); + if (tcp->th_flags & TH_FIN) + putchar('F'); + if (tcp->th_flags & TH_SYN) + putchar('S'); + if (tcp->th_flags & TH_RST) + putchar('R'); + if (tcp->th_flags & TH_PUSH) + putchar('P'); + if (tcp->th_flags & TH_ACK) + putchar('A'); + if (tcp->th_flags & TH_URG) + putchar('U'); + if (tcp->th_flags & TH_ECN) + putchar('E'); + if (tcp->th_flags & TH_CWR) + putchar('C'); + } + } + + putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printpacket6.c b/contrib/ipfilter/lib/printpacket6.c new file mode 100644 index 000000000000..2f9ea1dc5514 --- /dev/null +++ b/contrib/ipfilter/lib/printpacket6.c @@ -0,0 +1,43 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +/* + * This is meant to work without the IPv6 header files being present or + * the inet_ntop() library. + */ +void printpacket6(ip) +struct ip *ip; +{ + u_char *buf, p; + u_short plen, *addrs; + tcphdr_t *tcp; + u_32_t flow; + + buf = (u_char *)ip; + tcp = (tcphdr_t *)(buf + 40); + p = buf[6]; + flow = ntohl(*(u_32_t *)buf); + flow &= 0xfffff; + plen = ntohs(*((u_short *)buf +2)); + addrs = (u_short *)buf + 4; + + printf("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p); + printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), + ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), + ntohs(addrs[6]), ntohs(addrs[7])); + if (plen >= 4) + if (p == IPPROTO_TCP || p == IPPROTO_UDP) + (void)printf(",%d", ntohs(tcp->th_sport)); + printf(" >"); + addrs += 8; + printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), + ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), + ntohs(addrs[6]), ntohs(addrs[7])); + if (plen >= 4) + if (p == IPPROTO_TCP || p == IPPROTO_UDP) + (void)printf(",%d", ntohs(tcp->th_dport)); + putchar('\n'); +} diff --git a/contrib/ipfilter/lib/printpool.c b/contrib/ipfilter/lib/printpool.c new file mode 100644 index 000000000000..6291306395f4 --- /dev/null +++ b/contrib/ipfilter/lib/printpool.c @@ -0,0 +1,108 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +ip_pool_t *printpool(pp, copyfunc, name, opts) +ip_pool_t *pp; +copyfunc_t copyfunc; +char *name; +int opts; +{ + ip_pool_node_t *ipnp, *ipnpn, ipn; + ip_pool_t ipp; + + if ((*copyfunc)(pp, &ipp, sizeof(ipp))) + return NULL; + + if ((name != NULL) && strncmp(name, ipp.ipo_name, FR_GROUPLEN)) + return ipp.ipo_next; + + if ((opts & OPT_DEBUG) == 0) { + if ((ipp.ipo_flags & IPOOL_ANON) != 0) + PRINTF("# 'anonymous' tree %s\n", ipp.ipo_name); + PRINTF("table role = "); + } else { + PRINTF("Name: %s", ipp.ipo_name); + if ((ipp.ipo_flags & IPOOL_ANON) == IPOOL_ANON) + PRINTF("(anon)"); + putchar(' '); + PRINTF("Role: "); + } + + switch (ipp.ipo_unit) + { + case IPL_LOGIPF : + printf("ipf"); + break; + case IPL_LOGNAT : + printf("nat"); + break; + case IPL_LOGSTATE : + printf("state"); + break; + case IPL_LOGAUTH : + printf("auth"); + break; + case IPL_LOGSYNC : + printf("sync"); + break; + case IPL_LOGSCAN : + printf("scan"); + break; + case IPL_LOGLOOKUP : + printf("lookup"); + break; + case IPL_LOGCOUNT : + printf("count"); + break; + default : + printf("unknown(%d)", ipp.ipo_unit); + } + + if ((opts & OPT_DEBUG) == 0) { + PRINTF(" type = tree number = %s\n", ipp.ipo_name); + PRINTF("\t{"); + } else { + putchar(' '); + + PRINTF("\tReferences: %d\tHits: %lu\n", ipp.ipo_ref, + ipp.ipo_hits); + PRINTF("\tNodes Starting at %p\n", ipp.ipo_list); + } + + ipnpn = ipp.ipo_list; + ipp.ipo_list = NULL; + while (ipnpn != NULL) { + ipnp = (ip_pool_node_t *)malloc(sizeof(*ipnp)); + (*copyfunc)(ipnpn, ipnp, sizeof(ipn)); + ipnpn = ipnp->ipn_next; + ipnp->ipn_next = ipp.ipo_list; + ipp.ipo_list = ipnp; + } + + if (ipp.ipo_list == NULL) { + putchar(';'); + } else { + for (ipnp = ipp.ipo_list; ipnp != NULL; ) { + ipnp = printpoolnode(ipnp, opts); + + if ((opts & OPT_DEBUG) == 0) { + putchar(';'); + } + } + } + + if ((opts & OPT_DEBUG) == 0) + PRINTF(" };\n"); + + return ipp.ipo_next; +} diff --git a/contrib/ipfilter/lib/printpoolnode.c b/contrib/ipfilter/lib/printpoolnode.c new file mode 100644 index 000000000000..dd0ef9705403 --- /dev/null +++ b/contrib/ipfilter/lib/printpoolnode.c @@ -0,0 +1,33 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +ip_pool_node_t *printpoolnode(np, opts) +ip_pool_node_t *np; +int opts; +{ + + if ((opts & OPT_DEBUG) == 0) { + putchar(' '); + if (np->ipn_info == 1) + PRINTF("! "); + printip((u_32_t *)&np->ipn_addr.adf_addr.in4); + printmask((u_32_t *)&np->ipn_mask.adf_addr); + } else { + PRINTF("\t\t%s%s", np->ipn_info ? "! " : "", + inet_ntoa(np->ipn_addr.adf_addr.in4)); + printmask((u_32_t *)&np->ipn_mask.adf_addr); + PRINTF("\n\t\tHits %lu\tName %s\n", + np->ipn_hits, np->ipn_name); + } + return np->ipn_next; +} diff --git a/contrib/ipfilter/lib/printportcmp.c b/contrib/ipfilter/lib/printportcmp.c new file mode 100644 index 000000000000..7ec011604faf --- /dev/null +++ b/contrib/ipfilter/lib/printportcmp.c @@ -0,0 +1,29 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: printportcmp.c,v 1.7 2003/02/16 02:31:05 darrenr Exp + */ + +#include "ipf.h" + + +void printportcmp(pr, frp) +int pr; +frpcmp_t *frp; +{ + static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=", + "<>", "><", ":" }; + + if (frp->frp_cmp == FR_INRANGE || frp->frp_cmp == FR_OUTRANGE) + printf(" port %d %s %d", frp->frp_port, + pcmp1[frp->frp_cmp], frp->frp_top); + else if (frp->frp_cmp == FR_INCRANGE) + printf(" port %d:%d", frp->frp_port, frp->frp_top); + else + printf(" port %s %s", pcmp1[frp->frp_cmp], + portname(pr, frp->frp_port)); +} diff --git a/contrib/ipfilter/lib/printsbuf.c b/contrib/ipfilter/lib/printsbuf.c new file mode 100644 index 000000000000..805c03b0f71d --- /dev/null +++ b/contrib/ipfilter/lib/printsbuf.c @@ -0,0 +1,24 @@ +/* $NetBSD$ */ + +#ifdef IPFILTER_SCAN + +#include +#include +#include "ipf.h" +#include "netinet/ip_scan.h" + +void printsbuf(buf) +char *buf; +{ + u_char *s; + int i; + + for (s = (u_char *)buf, i = ISC_TLEN; i; i--, s++) { + if (ISPRINT(*s)) + putchar(*s); + else + printf("\\%o", *s); + } +} + +#endif diff --git a/contrib/ipfilter/lib/printstate.c b/contrib/ipfilter/lib/printstate.c new file mode 100644 index 000000000000..9cfdc8ab3fb6 --- /dev/null +++ b/contrib/ipfilter/lib/printstate.c @@ -0,0 +1,189 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ + +#include "ipf.h" +#include "kmem.h" + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf + +ipstate_t *printstate(sp, opts, now) +ipstate_t *sp; +int opts; +u_long now; +{ + ipstate_t ips; + synclist_t ipsync; + + if (kmemcpy((char *)&ips, (u_long)sp, sizeof(ips))) + return NULL; + + PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4)); + PRINTF("%s pass %#x pr %d state %d/%d bkt %d\n", + hostname(ips.is_v, &ips.is_dst.in4), ips.is_pass, ips.is_p, + ips.is_state[0], ips.is_state[1], ips.is_hv); + PRINTF("\ttag %u ttl %lu", ips.is_tag, ips.is_die - now); + + if (ips.is_p == IPPROTO_TCP) { + PRINTF("\n\t%hu -> %hu %x:%x %hu<<%d:%hu<<%d\n", + ntohs(ips.is_sport), ntohs(ips.is_dport), + ips.is_send, ips.is_dend, + ips.is_maxswin, ips.is_swinscale, + ips.is_maxdwin, ips.is_dwinscale); + PRINTF("\tcmsk %04x smsk %04x isc %p s0 %08x/%08x\n", + ips.is_smsk[0], ips.is_smsk[1], ips.is_isc, + ips.is_s0[0], ips.is_s0[1]); + PRINTF("\tFWD:ISN inc %x sumd %x\n", + ips.is_isninc[0], ips.is_sumd[0]); + PRINTF("\tREV:ISN inc %x sumd %x\n", + ips.is_isninc[1], ips.is_sumd[1]); +#ifdef IPFILTER_SCAN + PRINTF("\tsbuf[0] ["); + printsbuf(ips.is_sbuf[0]); + PRINTF("] sbuf[1] ["); + printsbuf(ips.is_sbuf[1]); + PRINTF("]\n"); +#endif + } else if (ips.is_p == IPPROTO_UDP) { + PRINTF(" %hu -> %hu\n", ntohs(ips.is_sport), + ntohs(ips.is_dport)); + } else if (ips.is_p == IPPROTO_GRE) { + PRINTF(" call %hx/%hx\n", ntohs(ips.is_gre.gs_call[0]), + ntohs(ips.is_gre.gs_call[1])); + } else if (ips.is_p == IPPROTO_ICMP +#ifdef USE_INET6 + || ips.is_p == IPPROTO_ICMPV6 +#endif + ) + PRINTF(" id %hu seq %hu type %d\n", ips.is_icmp.ici_id, + ips.is_icmp.ici_seq, ips.is_icmp.ici_type); + +#ifdef USE_QUAD_T + PRINTF("\tforward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n\tbackward: pkts in %qd bytes in %qd pkts out %qd bytes out %qd\n", + ips.is_pkts[0], ips.is_bytes[0], + ips.is_pkts[1], ips.is_bytes[1], + ips.is_pkts[2], ips.is_bytes[2], + ips.is_pkts[3], ips.is_bytes[3]); +#else + PRINTF("\tforward: pkts in %ld bytes in %ld pkts out %ld bytes out %ld\n\tbackward: pkts in %ld bytes in %ld pkts out %ld bytes out %ld\n", + ips.is_pkts[0], ips.is_bytes[0], + ips.is_pkts[1], ips.is_bytes[1], + ips.is_pkts[2], ips.is_bytes[2], + ips.is_pkts[3], ips.is_bytes[3]); +#endif + + PRINTF("\t"); + + /* + * Print out bits set in the result code for the state being + * kept as they would for a rule. + */ + if (FR_ISPASS(ips.is_pass)) { + PRINTF("pass"); + } else if (FR_ISBLOCK(ips.is_pass)) { + PRINTF("block"); + switch (ips.is_pass & FR_RETMASK) + { + case FR_RETICMP : + PRINTF(" return-icmp"); + break; + case FR_FAKEICMP : + PRINTF(" return-icmp-as-dest"); + break; + case FR_RETRST : + PRINTF(" return-rst"); + break; + default : + break; + } + } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) { + PRINTF("log"); + if (ips.is_pass & FR_LOGBODY) + PRINTF(" body"); + if (ips.is_pass & FR_LOGFIRST) + PRINTF(" first"); + } else if (FR_ISACCOUNT(ips.is_pass)) { + PRINTF("count"); + } else if (FR_ISPREAUTH(ips.is_pass)) { + PRINTF("preauth"); + } else if (FR_ISAUTH(ips.is_pass)) + PRINTF("auth"); + + if (ips.is_pass & FR_OUTQUE) + PRINTF(" out"); + else + PRINTF(" in"); + + if ((ips.is_pass & FR_LOG) != 0) { + PRINTF(" log"); + if (ips.is_pass & FR_LOGBODY) + PRINTF(" body"); + if (ips.is_pass & FR_LOGFIRST) + PRINTF(" first"); + if (ips.is_pass & FR_LOGORBLOCK) + PRINTF(" or-block"); + } + if (ips.is_pass & FR_QUICK) + PRINTF(" quick"); + if (ips.is_pass & FR_KEEPFRAG) + PRINTF(" keep frags"); + /* a given; no? */ + if (ips.is_pass & FR_KEEPSTATE) { + PRINTF(" keep state"); + if (ips.is_pass & FR_STATESYNC) + PRINTF(" ( sync )"); + } + PRINTF("\tIPv%d", ips.is_v); + PRINTF("\n"); + + PRINTF("\tpkt_flags & %x(%x) = %x,\t", + ips.is_flags & 0xf, ips.is_flags, + ips.is_flags >> 4); + PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk, + ips.is_opt); + PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", + ips.is_secmsk, ips.is_sec, ips.is_authmsk, + ips.is_auth); + PRINTF("\tis_flx %#x %#x %#x %#x\n", ips.is_flx[0][0], ips.is_flx[0][1], + ips.is_flx[1][0], ips.is_flx[1][1]); + PRINTF("\tinterfaces: in %s[%s", getifname(ips.is_ifp[0]), + ips.is_ifname[0]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[0]); + putchar(']'); + PRINTF(",%s[%s", getifname(ips.is_ifp[1]), ips.is_ifname[1]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[1]); + putchar(']'); + PRINTF(" out %s[%s", getifname(ips.is_ifp[2]), ips.is_ifname[2]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[2]); + putchar(']'); + PRINTF(",%s[%s", getifname(ips.is_ifp[3]), ips.is_ifname[3]); + if (opts & OPT_DEBUG) + PRINTF("/%p", ips.is_ifp[3]); + PRINTF("]\n"); + + if (ips.is_sync != NULL) { + + if (kmemcpy((char *)&ipsync, (u_long)ips.is_sync, sizeof(ipsync))) { + + PRINTF("\tSync status: status could not be retrieved\n"); + return NULL; + } + + PRINTF("\tSync status: idx %d num %d v %d pr %d rev %d\n", + ipsync.sl_idx, ipsync.sl_num, ipsync.sl_v, + ipsync.sl_p, ipsync.sl_rev); + + } else { + PRINTF("\tSync status: not synchronized\n"); + } + + return ips.is_next; +} diff --git a/contrib/ipfilter/lib/printtunable.c b/contrib/ipfilter/lib/printtunable.c new file mode 100644 index 000000000000..46e9f80b5c5e --- /dev/null +++ b/contrib/ipfilter/lib/printtunable.c @@ -0,0 +1,21 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +void printtunable(tup) +ipftune_t *tup; +{ + printf("%s\tmin %#lx\tmax %#lx\tcurrent ", + tup->ipft_name, tup->ipft_min, tup->ipft_max); + if (tup->ipft_sz == sizeof(u_long)) + printf("%lu\n", tup->ipft_vlong); + else if (tup->ipft_sz == sizeof(u_int)) + printf("%u\n", tup->ipft_vint); + else if (tup->ipft_sz == sizeof(u_short)) + printf("%hu\n", tup->ipft_vshort); + else if (tup->ipft_sz == sizeof(u_char)) + printf("%u\n", (u_int)tup->ipft_vchar); + else { + printf("sz = %d\n", tup->ipft_sz); + } +} diff --git a/contrib/ipfilter/lib/ratoi.c b/contrib/ipfilter/lib/ratoi.c new file mode 100644 index 000000000000..31ee122be0b0 --- /dev/null +++ b/contrib/ipfilter/lib/ratoi.c @@ -0,0 +1,26 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ratoi.c,v 1.4 2001/06/09 17:09:25 darrenr Exp + */ + +#include "ipf.h" + + +int ratoi(ps, pi, min, max) +char *ps; +int *pi, min, max; +{ + int i; + char *pe; + + i = (int)strtol(ps, &pe, 0); + if (*pe != '\0' || i < min || i > max) + return 0; + *pi = i; + return 1; +} diff --git a/contrib/ipfilter/lib/ratoui.c b/contrib/ipfilter/lib/ratoui.c new file mode 100644 index 000000000000..e4d0cbf08b8c --- /dev/null +++ b/contrib/ipfilter/lib/ratoui.c @@ -0,0 +1,26 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: ratoui.c,v 1.4 2001/06/09 17:09:25 darrenr Exp + */ + +#include "ipf.h" + + +int ratoui(ps, pi, min, max) +char *ps; +u_int *pi, min, max; +{ + u_int i; + char *pe; + + i = (u_int)strtol(ps, &pe, 0); + if (*pe != '\0' || i < min || i > max) + return 0; + *pi = i; + return 1; +} diff --git a/contrib/ipfilter/lib/remove_hash.c b/contrib/ipfilter/lib/remove_hash.c new file mode 100644 index 000000000000..256751ff5e79 --- /dev/null +++ b/contrib/ipfilter/lib/remove_hash.c @@ -0,0 +1,53 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_hash.c,v 1.1 2003/04/13 06:40:14 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int remove_hash(iphp, iocfunc) +iphtable_t *iphp; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtable_t iph; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_HASH; + op.iplo_unit = iphp->iph_unit; + strncpy(op.iplo_name, iphp->iph_name, sizeof(op.iplo_name)); + if (*op.iplo_name == '\0') + op.iplo_arg = IPHASH_ANON; + op.iplo_size = sizeof(iph); + op.iplo_struct = &iph; + + bzero((char *)&iph, sizeof(iph)); + iph.iph_unit = iphp->iph_unit; + iph.iph_type = iphp->iph_type; + strncpy(iph.iph_name, iphp->iph_name, sizeof(iph.iph_name)); + iph.iph_flags = iphp->iph_flags; + + if ((*iocfunc)(hashfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("remove_hash:SIOCLOOKUPDELTABLE"); + return -1; + } + + return 0; +} diff --git a/contrib/ipfilter/lib/remove_hashnode.c b/contrib/ipfilter/lib/remove_hashnode.c new file mode 100644 index 000000000000..5e5b6349fd6f --- /dev/null +++ b/contrib/ipfilter/lib/remove_hashnode.c @@ -0,0 +1,58 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_hashnode.c,v 1.1 2003/04/13 06:40:14 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int hashfd = -1; + + +int remove_hashnode(unit, name, node, iocfunc) +int unit; +char *name; +iphtent_t *node; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + iphtent_t ipe; + + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + hashfd = open(IPLOOKUP_NAME, O_RDWR); + if ((hashfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_HASH; + op.iplo_unit = unit; + op.iplo_size = sizeof(ipe); + op.iplo_struct = &ipe; + op.iplo_arg = 0; + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + + bzero((char *)&ipe, sizeof(ipe)); + bcopy((char *)&node->ipe_addr, (char *)&ipe.ipe_addr, + sizeof(ipe.ipe_addr)); + bcopy((char *)&node->ipe_mask, (char *)&ipe.ipe_mask, + sizeof(ipe.ipe_mask)); + + if (opts & OPT_DEBUG) { + printf("\t%s - ", inet_ntoa(ipe.ipe_addr.in4)); + printf("%s\n", inet_ntoa(ipe.ipe_mask.in4)); + } + + if ((*iocfunc)(hashfd, SIOCLOOKUPDELNODE, &op)) + if (!(opts & OPT_DONOTHING)) { + perror("remove_hash:SIOCLOOKUPDELNODE"); + return -1; + } + return 0; +} diff --git a/contrib/ipfilter/lib/remove_pool.c b/contrib/ipfilter/lib/remove_pool.c new file mode 100644 index 000000000000..3f5e0044eebb --- /dev/null +++ b/contrib/ipfilter/lib/remove_pool.c @@ -0,0 +1,50 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_pool.c,v 1.1 2003/04/13 06:40:14 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_htable.h" + +static int poolfd = -1; + + +int remove_pool(poolp, iocfunc) +ip_pool_t *poolp; +ioctlfunc_t iocfunc; +{ + iplookupop_t op; + ip_pool_t pool; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_type = IPLT_POOL; + op.iplo_unit = poolp->ipo_unit; + strncpy(op.iplo_name, poolp->ipo_name, sizeof(op.iplo_name)); + op.iplo_size = sizeof(pool); + op.iplo_struct = &pool; + + bzero((char *)&pool, sizeof(pool)); + pool.ipo_unit = poolp->ipo_unit; + strncpy(pool.ipo_name, poolp->ipo_name, sizeof(pool.ipo_name)); + pool.ipo_flags = poolp->ipo_flags; + + if ((*iocfunc)(poolfd, SIOCLOOKUPDELTABLE, &op)) + if ((opts & OPT_DONOTHING) == 0) { + perror("remove_pool:SIOCLOOKUPDELTABLE"); + return -1; + } + + return 0; +} diff --git a/contrib/ipfilter/lib/remove_poolnode.c b/contrib/ipfilter/lib/remove_poolnode.c new file mode 100644 index 000000000000..aff4694687cb --- /dev/null +++ b/contrib/ipfilter/lib/remove_poolnode.c @@ -0,0 +1,57 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2002 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: remove_poolnode.c,v 1.3 2003/11/22 10:14:36 darrenr Exp + */ + +#include +#include +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" + +static int poolfd = -1; + + +int remove_poolnode(unit, name, node, iocfunc) +int unit; +char *name; +ip_pool_node_t *node; +ioctlfunc_t iocfunc; +{ + ip_pool_node_t pn; + iplookupop_t op; + + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + poolfd = open(IPLOOKUP_NAME, O_RDWR); + if ((poolfd == -1) && ((opts & OPT_DONOTHING) == 0)) + return -1; + + op.iplo_unit = unit; + op.iplo_type = IPLT_POOL; + op.iplo_arg = 0; + strncpy(op.iplo_name, name, sizeof(op.iplo_name)); + op.iplo_struct = &pn; + op.iplo_size = sizeof(pn); + + bzero((char *)&pn, sizeof(pn)); + bcopy((char *)&node->ipn_addr, (char *)&pn.ipn_addr, + sizeof(pn.ipn_addr)); + bcopy((char *)&node->ipn_mask, (char *)&pn.ipn_mask, + sizeof(pn.ipn_mask)); + pn.ipn_info = node->ipn_info; + strncpy(pn.ipn_name, node->ipn_name, sizeof(pn.ipn_name)); + + if ((*iocfunc)(poolfd, SIOCLOOKUPDELNODE, &op)) { + if ((opts & OPT_DONOTHING) == 0) { + perror("remove_pool:SIOCLOOKUPDELNODE"); + return -1; + } + } + + return 0; +} diff --git a/contrib/ipfilter/lib/resetlexer.c b/contrib/ipfilter/lib/resetlexer.c new file mode 100644 index 000000000000..0801242fdadc --- /dev/null +++ b/contrib/ipfilter/lib/resetlexer.c @@ -0,0 +1,17 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +long string_start = -1; +long string_end = -1; +char *string_val = NULL; +long pos = 0; + + +void resetlexer() +{ + string_start = -1; + string_end = -1; + string_val = NULL; + pos = 0; +} diff --git a/contrib/ipfilter/lib/rwlock_emul.c b/contrib/ipfilter/lib/rwlock_emul.c new file mode 100644 index 000000000000..64b807e494a2 --- /dev/null +++ b/contrib/ipfilter/lib/rwlock_emul.c @@ -0,0 +1,125 @@ +/* $NetBSD$ */ + +#include "ipf.h" + +#define EMM_MAGIC 0x97dd8b3a + +void eMrwlock_read_enter(rw, file, line) +eMrwlock_t *rw; +char *file; +int line; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { + fprintf(stderr, + "%s:eMrwlock_read_enter(%p): already locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + rw->eMrw_read++; + rw->eMrw_heldin = file; + rw->eMrw_heldat = line; +} + + +void eMrwlock_write_enter(rw, file, line) +eMrwlock_t *rw; +char *file; +int line; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 0 || rw->eMrw_write != 0) { + fprintf(stderr, + "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + rw->eMrw_write++; + rw->eMrw_heldin = file; + rw->eMrw_heldat = line; +} + + +void eMrwlock_downgrade(rw, file, line) +eMrwlock_t *rw; +char *file; +int line; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 0 || rw->eMrw_write != 1) { + fprintf(stderr, + "%s:eMrwlock_write_enter(%p): already locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + rw->eMrw_write--; + rw->eMrw_read++; + rw->eMrw_heldin = file; + rw->eMrw_heldat = line; +} + + +void eMrwlock_exit(rw) +eMrwlock_t *rw; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + if (rw->eMrw_read != 1 && rw->eMrw_write != 1) { + fprintf(stderr, "%s:eMrwlock_exit(%p): not locked: %d/%d\n", + rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write); + abort(); + } + if (rw->eMrw_read == 1) + rw->eMrw_read--; + else if (rw->eMrw_write == 1) + rw->eMrw_write--; + rw->eMrw_heldin = NULL; + rw->eMrw_heldat = 0; +} + + +void eMrwlock_init(rw, who) +eMrwlock_t *rw; +char *who; +{ + if (rw->eMrw_magic == EMM_MAGIC) { /* safe bet ? */ + fprintf(stderr, + "%s:eMrwlock_init(%p): already initialised?: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + rw->eMrw_magic = EMM_MAGIC; + rw->eMrw_read = 0; + rw->eMrw_write = 0; + if (who != NULL) + rw->eMrw_owner = strdup(who); + else + rw->eMrw_owner = NULL; +} + + +void eMrwlock_destroy(rw) +eMrwlock_t *rw; +{ + if (rw->eMrw_magic != EMM_MAGIC) { + fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n", + rw->eMrw_owner, rw, rw->eMrw_magic); + abort(); + } + memset(rw, 0xa5, sizeof(*rw)); +} diff --git a/contrib/ipfilter/lib/tcp_flags.c b/contrib/ipfilter/lib/tcp_flags.c new file mode 100644 index 000000000000..314b9d2ad230 --- /dev/null +++ b/contrib/ipfilter/lib/tcp_flags.c @@ -0,0 +1,50 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: tcp_flags.c,v 1.8 2004/02/07 18:15:54 darrenr Exp + */ + +#include "ipf.h" + +extern char flagset[]; +extern u_char flags[]; + + +u_char tcp_flags(flgs, mask, linenum) +char *flgs; +u_char *mask; +int linenum; +{ + u_char tcpf = 0, tcpfm = 0; + char *s; + + s = strchr(flgs, '/'); + if (s) + *s++ = '\0'; + + if (*flgs == '0') { + tcpf = strtol(flgs, NULL, 0); + } else { + tcpf = tcpflags(flgs); + } + + if (s != NULL) { + if (*s == '0') + tcpfm = strtol(s, NULL, 0); + else + tcpfm = tcpflags(s); + } + + if (!tcpfm) { + if (tcpf == TH_SYN) + tcpfm = 0xff & ~(TH_ECN|TH_CWR); + else + tcpfm = 0xff & ~(TH_ECN); + } + *mask = tcpfm; + return tcpf; +} diff --git a/contrib/ipfilter/lib/tcpflags.c b/contrib/ipfilter/lib/tcpflags.c new file mode 100644 index 000000000000..b7ea4b8c307e --- /dev/null +++ b/contrib/ipfilter/lib/tcpflags.c @@ -0,0 +1,45 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: tcpflags.c,v 1.3 2002/11/02 07:18:01 darrenr Exp + */ + +#include "ipf.h" + + +/* + * ECN is a new addition to TCP - RFC 2481 + */ +#ifndef TH_ECN +# define TH_ECN 0x40 +#endif +#ifndef TH_CWR +# define TH_CWR 0x80 +#endif + +extern char flagset[]; +extern u_char flags[]; + + +u_char tcpflags(flgs) +char *flgs; +{ + u_char tcpf = 0; + char *s, *t; + + for (s = flgs; *s; s++) { + if (*s == 'W') + tcpf |= TH_CWR; + else { + if (!(t = strchr(flagset, *s))) { + return 0; + } + tcpf |= flags[t - flagset]; + } + } + return tcpf; +} diff --git a/contrib/ipfilter/lib/tcpoptnames.c b/contrib/ipfilter/lib/tcpoptnames.c new file mode 100644 index 000000000000..b5e0cc77d67f --- /dev/null +++ b/contrib/ipfilter/lib/tcpoptnames.c @@ -0,0 +1,22 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: tcpoptnames.c,v 1.5 2002/01/28 06:50:48 darrenr Exp + */ + +#include "ipf.h" + + +struct ipopt_names tcpoptnames[] ={ + { TCPOPT_NOP, 0x000001, 1, "nop" }, + { TCPOPT_MAXSEG, 0x000002, 4, "maxseg" }, + { TCPOPT_WINDOW, 0x000004, 3, "wscale" }, + { TCPOPT_SACK_PERMITTED, 0x000008, 2, "sackok" }, + { TCPOPT_SACK, 0x000010, 3, "sack" }, + { TCPOPT_TIMESTAMP, 0x000020, 10, "tstamp" }, + { 0, 0, 0, (char *)NULL } /* must be last */ +}; diff --git a/contrib/ipfilter/lib/to_interface.c b/contrib/ipfilter/lib/to_interface.c new file mode 100644 index 000000000000..50f9a70e8f9f --- /dev/null +++ b/contrib/ipfilter/lib/to_interface.c @@ -0,0 +1,31 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: to_interface.c,v 1.8 2002/01/28 06:50:48 darrenr Exp + */ + +#include "ipf.h" + + +int to_interface(fdp, to, linenum) +frdest_t *fdp; +char *to; +int linenum; +{ + char *s; + + s = strchr(to, ':'); + fdp->fd_ifp = NULL; + if (s) { + *s++ = '\0'; + if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum, NULL) == -1) + return -1; + } + (void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1); + fdp->fd_ifname[sizeof(fdp->fd_ifname) - 1] = '\0'; + return 0; +} diff --git a/contrib/ipfilter/lib/v6ionames.c b/contrib/ipfilter/lib/v6ionames.c new file mode 100644 index 000000000000..087da5d8a8d0 --- /dev/null +++ b/contrib/ipfilter/lib/v6ionames.c @@ -0,0 +1,27 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: v6ionames.c,v 1.1.4.1 2005/01/02 13:08:49 darrenr Exp + */ +#include "ipf.h" + + +#ifdef USE_INET6 + +struct ipopt_names v6ionames[] ={ + { IPPROTO_HOPOPTS, 0x000001, 0, "hopopts" }, + { IPPROTO_IPV6, 0x000002, 0, "ipv6" }, + { IPPROTO_ROUTING, 0x000004, 0, "routing" }, + { IPPROTO_FRAGMENT, 0x000008, 0, "frag" }, + { IPPROTO_ESP, 0x000010, 0, "esp" }, + { IPPROTO_AH, 0x000020, 0, "ah" }, + { IPPROTO_NONE, 0x000040, 0, "none" }, + { IPPROTO_DSTOPTS, 0x000080, 0, "dstopts" }, + { 0, 0, 0, (char *)NULL } +}; + +#endif diff --git a/contrib/ipfilter/lib/v6optvalue.c b/contrib/ipfilter/lib/v6optvalue.c new file mode 100644 index 000000000000..57dc2fbfb4e4 --- /dev/null +++ b/contrib/ipfilter/lib/v6optvalue.c @@ -0,0 +1,39 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: v6optvalue.c,v 1.1 2003/04/26 04:55:58 darrenr Exp + */ +#include "ipf.h" + + + +u_32_t getv6optbyname(optname) +char *optname; +{ +#ifdef USE_INET6 + struct ipopt_names *io; + + for (io = v6ionames; io->on_name; io++) + if (!strcasecmp(optname, io->on_name)) + return io->on_bit; +#endif + return -1; +} + + +u_32_t getv6optbyvalue(optval) +int optval; +{ +#ifdef USE_INET6 + struct ipopt_names *io; + + for (io = v6ionames; io->on_name; io++) + if (io->on_value == optval) + return io->on_bit; +#endif + return -1; +} diff --git a/contrib/ipfilter/lib/var.c b/contrib/ipfilter/lib/var.c new file mode 100644 index 000000000000..79b2517b9ae2 --- /dev/null +++ b/contrib/ipfilter/lib/var.c @@ -0,0 +1,171 @@ +/* $NetBSD$ */ + +#include + +#include "ipf.h" + +typedef struct variable { + struct variable *v_next; + char *v_name; + char *v_value; +} variable_t; + +static variable_t *vtop = NULL; + +static variable_t *find_var __P((char *)); +static char *expand_string __P((char *, int)); + + +static variable_t *find_var(name) +char *name; +{ + variable_t *v; + + for (v = vtop; v != NULL; v = v->v_next) + if (!strcmp(name, v->v_name)) + return v; + return NULL; +} + + +char *get_variable(string, after, line) +char *string, **after; +int line; +{ + char c, *s, *t, *value; + variable_t *v; + + s = string; + + if (*s == '{') { + s++; + for (t = s; *t != '\0'; t++) + if (*t == '}') + break; + if (*t == '\0') { + fprintf(stderr, "%d: { without }\n", line); + return NULL; + } + } else if (ISALPHA(*s)) { + for (t = s + 1; *t != '\0'; t++) + if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_')) + break; + } else { + fprintf(stderr, "%d: variables cannot start with '%c'\n", + line, *s); + return NULL; + } + + if (after != NULL) + *after = t; + c = *t; + *t = '\0'; + v = find_var(s); + *t = c; + if (v == NULL) { + fprintf(stderr, "%d: unknown variable '%s'\n", line, s); + return NULL; + } + + s = strdup(v->v_value); + value = expand_string(s, line); + if (value != s) + free(s); + return value; +} + + +static char *expand_string(oldstring, line) +char *oldstring; +int line; +{ + char c, *s, *p1, *p2, *p3, *newstring, *value; + int len; + + p3 = NULL; + newstring = oldstring; + + for (s = oldstring; *s != '\0'; s++) + if (*s == '$') { + *s = '\0'; + s++; + + switch (*s) + { + case '$' : + bcopy(s, s - 1, strlen(s)); + break; + default : + c = *s; + if (c == '\0') + return newstring; + + value = get_variable(s, &p3, line); + if (value == NULL) + return NULL; + + p2 = expand_string(value, line); + if (p2 == NULL) + return NULL; + + len = strlen(newstring) + strlen(p2); + if (p3 != NULL) { + if (c == '{' && *p3 == '}') + p3++; + len += strlen(p3); + } + p1 = malloc(len + 1); + if (p1 == NULL) + return NULL; + + *(s - 1) = '\0'; + strcpy(p1, newstring); + strcat(p1, p2); + if (p3 != NULL) + strcat(p1, p3); + + s = p1 + len - strlen(p3) - 1; + if (newstring != oldstring) + free(newstring); + newstring = p1; + break; + } + } + return newstring; +} + + +void set_variable(name, value) +char *name; +char *value; +{ + variable_t *v; + int len; + + if (name == NULL || value == NULL || *name == '\0') + return; + + v = find_var(name); + if (v != NULL) { + free(v->v_value); + v->v_value = strdup(value); + return; + } + + len = strlen(value); + + if ((*value == '"' && value[len - 1] == '"') || + (*value == '\'' && value[len - 1] == '\'')) { + value[len - 1] = '\0'; + value++; + len -=2; + } + + v = (variable_t *)malloc(sizeof(*v)); + if (v == NULL) + return; + v->v_name = strdup(name); + v->v_value = strdup(value); + v->v_next = vtop; + vtop = v; +} diff --git a/contrib/ipfilter/lib/verbose.c b/contrib/ipfilter/lib/verbose.c new file mode 100644 index 000000000000..d4f3012ca6f8 --- /dev/null +++ b/contrib/ipfilter/lib/verbose.c @@ -0,0 +1,37 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: verbose.c,v 1.6 2001/06/09 17:09:25 darrenr Exp + */ + +#if defined(__STDC__) +# include +#else +# include +#endif +#include + +#include "ipt.h" +#include "opts.h" + + +#if defined(__STDC__) +void verbose(char *fmt, ...) +#else +void verbose(fmt, va_alist) +char *fmt; +va_dcl +#endif +{ + va_list pvar; + + va_start(pvar, fmt); + + if (opts & OPT_VERBOSE) + vprintf(fmt, pvar); + va_end(pvar); +} diff --git a/contrib/ipfilter/man/Makefile b/contrib/ipfilter/man/Makefile index 05164d7c818f..3f12ccbe87b4 100644 --- a/contrib/ipfilter/man/Makefile +++ b/contrib/ipfilter/man/Makefile @@ -1,9 +1,7 @@ # # 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. # all: @@ -12,12 +10,19 @@ install: $(INSTALL) -m 0644 -c -o root -g bin ipftest.1 $(MANDIR)/man1 $(INSTALL) -m 0644 -c -o root -g bin ipnat.8 $(MANDIR)/man8 $(INSTALL) -m 0644 -c -o root -g bin ipf.4 $(MANDIR)/man4 + $(INSTALL) -m 0644 -c -o root -g bin ipfilter.4 $(MANDIR)/man4 $(INSTALL) -m 0644 -c -o root -g bin ipl.4 $(MANDIR)/man4 $(INSTALL) -m 0644 -c -o root -g bin ipnat.4 $(MANDIR)/man4 $(INSTALL) -m 0644 -c -o root -g bin ipf.5 $(MANDIR)/man5 + $(INSTALL) -m 0644 -c -o root -g bin ipfilter.5 $(MANDIR)/man5 $(INSTALL) -m 0644 -c -o root -g bin ipnat.5 $(MANDIR)/man5 $(INSTALL) -m 0644 -c -o root -g bin ipf.8 $(MANDIR)/man8 $(INSTALL) -m 0644 -c -o root -g bin ipfs.8 $(MANDIR)/man8 $(INSTALL) -m 0644 -c -o root -g bin ipmon.8 $(MANDIR)/man8 + $(INSTALL) -m 0644 -c -o root -g bin ipmon.5 $(MANDIR)/man5 + $(INSTALL) -m 0644 -c -o root -g bin ippool.8 $(MANDIR)/man8 + $(INSTALL) -m 0644 -c -o root -g bin ippool.5 $(MANDIR)/man5 + $(INSTALL) -m 0644 -c -o root -g bin ipscan.8 $(MANDIR)/man8 + $(INSTALL) -m 0644 -c -o root -g bin ipscan.5 $(MANDIR)/man5 $(INSTALL) -m 0644 -c -o root -g bin ipfstat.8 $(MANDIR)/man8 @echo "Remember to rebuild the whatis database." diff --git a/contrib/ipfilter/man/ipfilter.4 b/contrib/ipfilter/man/ipfilter.4 new file mode 100644 index 000000000000..cf8ca9fa5f10 --- /dev/null +++ b/contrib/ipfilter/man/ipfilter.4 @@ -0,0 +1,241 @@ +.\" $NetBSD$ +.\" +.TH IP\ FILTER 4 +.SH NAME +ipfilter \- Introduction to IP packet filtering +.SH DESCRIPTION +IP Filter is a TCP/IP packet filter, suitable for use in a firewall +environment. To use, it can either be used as a loadable kernel module or +incorporated into your UNIX kernel; use as a loadable kernel module where +possible is highly recommended. Scripts are provided to install and patch +system files, as required. +.SH FEATURES +The IP packet filter can: +.IP +explicitly deny/permit any packet from passing through +.IP +distinguish between various interfaces +.IP +filter by IP networks or hosts +.IP +selectively filter any IP protocol +.IP +selectively filter fragmented IP packets +.IP +selectively filter packets with IP options +.IP +send back an ICMP error/TCP reset for blocked packets +.IP +keep packet state information for TCP, UDP and ICMP packet flows +.IP +keep fragment state information for any IP packet, applying the same rule +to all fragments. +.IP +act as a Network Address Translator (NAT) +.IP +use redirection to setup true transparent proxy connections +.IP +provide packet header details to a user program for authentication +.IP +in addition, supports temporary storage of pre-authenticated rules for passing packets through +.PP +Special provision is made for the three most common Internet protocols, TCP, +UDP and ICMP. The IP Packet filter allows filtering of: +.IP +Inverted host/net matchingTCP/UDP packets by port number or a port number +range +.IP +ICMP packets by type/code +.IP +"established" TCP packets +.IP +On any arbitrary combination of TCP flags +.IP +"short" (fragmented) IP packets with incomplete headers can be filtered +.IP +any of the 19 IP options or 8 registered IP security classes TOS (Type of +Service) field in packets +.PP +To keep track of the performance of the IP packet filter, a logging device +is used which supports logging of: +.IP +the TCP/UDP/ICMP and IP packet headers +.IP +the first 128 bytes of the packet (including headers) +.PP +A packet can be logged when: +.IP +it is successfully passed through +.IP +it is blocked from passing through +.IP +it matches a rule setup to look for suspicious packets +.PP +IP Filter keeps its own set of statistics on: +.IP +packets blocked +.IP +packets (and bytes!) used for accounting +.IP +packets passed +.lP +packets logged +.IP +attempts to log which failed (buffer full) +.IP +and much more, for packets going both in and out. + +.SH Tools +The current implementation provides a small set of tools, which can easily +be used and integrated with regular unix shells and tools. A brief description +of the tools provided: +.PP +ipf(8) +reads in a set of rules, from either stdin or a file, and adds them to +the kernels current list (appending them). It can also be used to flush the +current filter set or delete individual filter rules. The file format is +described in ipf(5). +.PP +ipfs(8) +is a utility to temporarily lock the IP Filter kernel tables (state tables +and NAT mappings) and write them to disk. After that the system can be +rebooted, and ipfs can be used to read these tables from disk and restore +them into the kernel. This way the system can be rebooted without the +connections being terminated. +.PP +ipfstat(8) +interrogates the kernel for statistics on packet filtering, so +far, and retrieves the list of filters in operation for inbound and outbound +packets. +.PP +ipftest(1) +reads in a filter rule file and then applies sample IP packets to +the rule file. This allows for testing of filter list and examination of how +a packet is passed along through it. +.PP +ipmon(8) +reads buffered data from the logging device (default is /dev/ipl) +for output to either: +.IP +screen (standard output) +.IP +file +.IP +syslog +.PP +ipsend(1) +generates arbitary IP packets for ethernet connected machines. +.PP +ipresend(1) +reads in a data file of saved IP packets (ie +snoop/tcpdump/etherfind output) and sends it back across the network. +.PP +iptest(1) +contains a set of test "programs" which send out a series of IP +packets, aimed at testing the strength of the TCP/IP stack at which it is +aimed at. WARNING: this may crash machine(s) targeted! +.PP +ipnat(8) +reads in a set of rules, from either stdin or a file and adds them +to the kernels current list of active NAT rules. NAT rules can also be +deleted using ipnat. The format of the configuration file to be used +with ipnat is described in ipnat(5). +.PP +For use in your own programs (e.g. for writing of transparent application +proxies), the programming interface and the associated ioctl's are +documented in ipf(4). + +Documentation on ioctl's and the format of data saved +to the logging character device is provided in ipl(4) +so that you may develop your own applications to work with or in place of any +of the above. + +Similar, the interface to the NAT code is documented in ipnat(4). + +.SH PACKET PROCESSING FLOW +The following diagram illustrates the flow of TCP/IP packets through the +various stages introduced by IP Filter. +.PP +.nf + IN + | + V + +-------------------------+--------------------------+ + | | | + | V | + | Network Address Translation | + | | | + | authenticated | | + | +-------<---------+ | + | | | | + | | V | + | V IP Accounting | + | | | | + | | V | + | | Fragment Cache Check--+ | + | | | | | + | V V V | + | | Packet State Check-->+ | + | | | | | + | | +->--+ | | | + | | | | V | | + | V groups IP Filtering V | + | | | | | | | + | | +--<-+ | | | + | | | | | + | +---------------->|<-----------+ | + | | | + | V | + | +---<----+ | + | | | | + | function | | + | | V | + | +--->----+ | + | | | + | V | + +--|---<--- fast-route ---<--+ | + | | | | + | | V | + | +-------------------------+--------------------------+ + | | + | pass only + | | + | V + V [KERNEL TCP/IP Processing] + | | + | +-------------------------+--------------------------+ + | | | | + | | V | + | | Fragment Cache Check--+ | + | | | | | + | | V V | + | | Packet State Check-->+ | + | | | | | + | | V | | + V | IP Filtering | | + | | | V | + | | |<-----------+ | + | | V | + | | IP Accounting | + | | | | + | | V | + | | Network Address Translation | + | | | | + | | V | + | +-------------------------+--------------------------+ + | | + | pass only + V | + +--------------------------->| + V + OUT +.fi + +.SH MORE INFORMATION +More information (including pointers to the FAQ and the mailing list) can be +obtained from the sofware's official homepage: www.ipfilter.org + +.SH SEE ALSO +ipf(4), ipf(5), ipf(8), ipfilter(5), ipfs(8), ipfstat(8), ipftest(1), +ipl(4), ipmon(8), ipnat(8), ipnat(4), + diff --git a/contrib/ipfilter/man/ipfilter.4.mandoc b/contrib/ipfilter/man/ipfilter.4.mandoc new file mode 100644 index 000000000000..72534a759761 --- /dev/null +++ b/contrib/ipfilter/man/ipfilter.4.mandoc @@ -0,0 +1,267 @@ +.Dd December 8, 2000 +.Dt IP\ FILTER 4 +.Os +.Sh NAME +.Nm IP Filter +.Nd Introduction to IP packet filtering +.Sh DESCRIPTION +IP Filter is a TCP/IP packet filter, suitable for use in a firewall +environment. To use, it can either be used as a loadable kernel module or +incorporated into your UNIX kernel; use as a loadable kernel module where +possible is highly recommended. Scripts are provided to install and patch +system files, as required. +.Sh FEATURES +The IP packet filter can: +.Bl -bullet -offset indent -compact +.It +explicitly deny/permit any packet from passing through +.It +distinguish between various interfaces +.It +filter by IP networks or hosts +.It +selectively filter any IP protocol +.It +selectively filter fragmented IP packets +.It +selectively filter packets with IP options +.It +send back an ICMP error/TCP reset for blocked packets +.It +keep packet state information for TCP, UDP and ICMP packet flows +.It +keep fragment state information for any IP packet, applying the same rule +to all fragments. +.It +act as a Network Address Translator (NAT) +.It +use redirection to setup true transparent proxy connections +.It +provide packet header details to a user program for authentication +.It +in addition, supports temporary storage of pre-authenticated rules for passing packets through +.El +.Pp +Special provision is made for the three most common Internet protocols, TCP, +UDP and ICMP. The IP Packet filter allows filtering of: +.Bl -bullet -offset indent -compact +.It +Inverted host/net matchingTCP/UDP packets by port number or a port number +range +.It +ICMP packets by type/code +.It +"established" TCP packets +.It +On any arbitrary combination of TCP flags +.It +"short" (fragmented) IP packets with incomplete headers can be filtered +.It +any of the 19 IP options or 8 registered IP security classes TOS (Type of +Service) field in packets +.El +.Pp +To keep track of the performance of the IP packet filter, a logging device +is used which supports logging of: +.Bl -bullet -offset indent -compact +.It +the TCP/UDP/ICMP and IP packet headers +.It +the first 128 bytes of the packet (including headers) +.El +.Pp +A packet can be logged when: +.Bl -bullet -offset indent -compact +.It +it is successfully passed through +.It +it is blocked from passing through +.It +it matches a rule setup to look for suspicious packets +.El +.Pp +IP Filter keeps its own set of statistics on: +.Bl -bullet -offset indent -compact +.It +packets blocked +.It +packets (and bytes!) used for accounting +.It +packets passed +.li +packets logged +.It +attempts to log which failed (buffer full) +.El +and much more, for packets going both in and out. + +.Sh Tools +The current implementation provides a small set of tools, which can easily +be used and integrated with regular unix shells and tools. A brief description +of the tools provided: +.Pp +.Xr ipf 8 +reads in a set of rules, from either stdin or a file, and adds them to +the kernels current list (appending them). It can also be used to flush the +current filter set or delete individual filter rules. The file format is +described in +.Xr ipf 5 . +.Pp +.Xr ipfs 8 +is a utility to temporarily lock the IP Filter kernel tables (state tables +and NAT mappings) and write them to disk. After that the system can be +rebooted, and ipfs can be used to read these tables from disk and restore +them into the kernel. This way the system can be rebooted without the +connections being terminated. +.Pp +.Xr ipfstat 8 +interrogates the kernel for statistics on packet filtering, so +far, and retrieves the list of filters in operation for inbound and outbound +packets. +.Pp +.Xr ipftest 1 +reads in a filter rule file and then applies sample IP packets to +the rule file. This allows for testing of filter list and examination of how +a packet is passed along through it. +.Pp +.Xr ipmon 8 +reads buffered data from the logging device (default is /dev/ipl) +for output to either: +.Bl -bullet -offset indent -compact +.It +screen (standard output) +.It +file +.It +syslog +.El +.Pp +.Xr ipsend 1 +generates arbitary IP packets for ethernet connected machines. +.Pp +.Xr ipresend 1 +reads in a data file of saved IP packets (ie +snoop/tcpdump/etherfind output) and sends it back across the network. +.Pp +.Xr iptest 1 +contains a set of test "programs" which send out a series of IP +packets, aimed at testing the strength of the TCP/IP stack at which it is +aimed at. WARNING: this may crash machine(s) targeted! +.Pp +.Xr ipnat 8 +reads in a set of rules, from either stdin or a file and adds them +to the kernels current list of active NAT rules. NAT rules can also be +deleted using ipnat. The format of the configuration file to be used +with ipnat is described in +.Xr ipnat 5 . +.Pp +For use in your own programs (e.g. for writing of transparent application +proxies), the programming interface and the associated ioctl's are +documented in +.Xr ipf 4 . + +Documentation on ioctl's and the format of data saved +to the logging character device is provided in +.Xr ipl 4 +so that you may develop your own applications to work with or in place of any +of the above. + +Similar, the interface to the NAT code is documented in +.Xr ipnat 4 . + +.Sh PACKET PROCESSING FLOW +The following diagram illustrates the flow of TCP/IP packets through the +various stages introduced by IP Filter. +.Pp +.nf + IN + | + V + +-------------------------+--------------------------+ + | | | + | V | + | Network Address Translation | + | | | + | authenticated | | + | +-------<---------+ | + | | | | + | | V | + | V IP Accounting | + | | | | + | | V | + | | Fragment Cache Check--+ | + | | | | | + | V V V | + | | Packet State Check-->+ | + | | | | | + | | +->--+ | | | + | | | | V | | + | V groups IP Filtering V | + | | | | | | | + | | +--<-+ | | | + | | | | | + | +---------------->|<-----------+ | + | | | + | V | + | +---<----+ | + | | | | + | function | | + | | V | + | +--->----+ | + | | | + | V | + +--|---<--- fast-route ---<--+ | + | | | | + | | V | + | +-------------------------+--------------------------+ + | | + | pass only + | | + | V + V [KERNEL TCP/IP Processing] + | | + | +-------------------------+--------------------------+ + | | | | + | | V | + | | Fragment Cache Check--+ | + | | | | | + | | V V | + | | Packet State Check-->+ | + | | | | | + | | V | | + V | IP Filtering | | + | | | V | + | | |<-----------+ | + | | V | + | | IP Accounting | + | | | | + | | V | + | | Network Address Translation | + | | | | + | | V | + | +-------------------------+--------------------------+ + | | + | pass only + V | + +--------------------------->| + V + OUT +.fi + +.Sh MORE INFORMATION +More information (including pointers to the FAQ and the mailing list) can be +obtained from the sofware's official homepage: www.ipfilter.org + +.Sh SEE ALSO +.Xr ipf 4 , +.Xr ipf 5 , +.Xr ipf 8 , +.Xr ipfilter 5 , +.Xr ipfs 8 , +.Xr ipfstat 8 , +.Xr ipftest 1 , +.Xr ipl 4 , +.Xr ipmon 8 , +.Xr ipnat 4 , +.Xr ipnat 8 , + diff --git a/contrib/ipfilter/man/ipfs.8 b/contrib/ipfilter/man/ipfs.8 index b07935a9e350..52f6fcbf0be9 100644 --- a/contrib/ipfilter/man/ipfs.8 +++ b/contrib/ipfilter/man/ipfs.8 @@ -1,3 +1,5 @@ +.\" $NetBSD$ +.\" .TH IPFS 8 .SH NAME ipfs \- saves and restores information for NAT and state tables. @@ -54,7 +56,7 @@ and options for saving state information. .TP .B \-n -Don't actually take any action that would effect information stored in +Don't actually take any action that would affect information stored in the kernel or on disk. .TP .B \-v @@ -90,17 +92,17 @@ and does not change the lock once complete. .B \-R Restores all saved state information, if any, from two files, \fIipstate.ipf\fP and \fIipnat.ipf\fP, stored in the \fI/var/db/ipf\fP -directory unless otherwise specified the +directory unless otherwise specified by the .B \-d -option is used. The state tables are locked at the beginning of this +option. The state tables are locked at the beginning of this operation and unlocked once complete. .TP .B \-W Saves in-kernel state information, if any, out to two files, \fIipstate.ipf\fP and \fIipnat.ipf\fP, stored in the \fI/var/db/ipf\fP -directory unless otherwise specified the +directory unless otherwise specified by the .B \-d -option is used. The state tables are locked at the beginning of this +option. The state tables are locked at the beginning of this operation and unlocked once complete. .DT .SH FILES diff --git a/contrib/ipfilter/man/ipl.4 b/contrib/ipfilter/man/ipl.4 index 0368f03ba15b..d45749b6750e 100644 --- a/contrib/ipfilter/man/ipl.4 +++ b/contrib/ipfilter/man/ipl.4 @@ -1,3 +1,5 @@ +.\" $NetBSD$ +.\" .TH IPL 4 .SH NAME ipl \- IP packet log device @@ -50,7 +52,7 @@ a buffer big enough to hold at least 1 complete log record - reading of partial log records is not supported. .PP If the packet contents are more than 128 bytes when \fBlog body\fP is used, -then only 128 bytes of the packet contents is logged. +then only 128 bytes of the packet contents are logged. .PP Although it is only possible to read from the \fBipl\fP device, opening it for writing is required when using an ioctl which changes any kernel data. @@ -76,4 +78,4 @@ ipf(4) .SH BUGS Packet headers are dropped when the internal buffer (static size) fills. .SH FILES -/dev/ipl +/dev/ipl0 diff --git a/contrib/ipfilter/man/ipmon.5 b/contrib/ipfilter/man/ipmon.5 new file mode 100644 index 000000000000..bc48466bc718 --- /dev/null +++ b/contrib/ipfilter/man/ipmon.5 @@ -0,0 +1,69 @@ +.\" $NetBSD$ +.\" +.TH IPMON 5 +.SH NAME +ipmon, ipmon.conf \- ipmon configuration file format +.SH DESCRIPTION +The format for files accepted by ipmon is described by the following grammar: +.LP +.nf +"match" "{" matchlist "}" "do" "{" doing "}" ";" + +matchlist ::= matching [ "," matching ] . +matching ::= direction | dstip | dstport | every | group | interface | + logtag | nattag | protocol | result | rule | srcip | srcport . + +dolist ::= doing [ "," doing ] . +doing ::= execute | save | syslog . + +direction ::= "in" | "out" . +dstip ::= "dstip" "=" ipv4 "/" number . +dstport ::= "dstport" "=" number . +every ::= "every" every-options . +execute ::= "execute" "=" string . +group ::= "group" "=" string | "group" "=" number . +interface ::= "interface" "=" string . +logtag ::= "logtag" "=" string | "logtag" "=" number . +nattag ::= "nattag" "=" string . +protocol ::= "protocol" "=" string | "protocol" "=" number . +result ::= "result" "=" result-option . +rule ::= "rule" "=" number . +srcip ::= "srcip" "=" ipv4 "/" number . +srcport ::= "srcport" "=" number . +type ::= "type" "=" ipftype . +ipv4 ::= number "." number "." number "." number . + +every-options ::= "second" | number "seconds" | "packet" | number "packets" . +result-option ::= "pass" | "block" | "short" | "nomatch" | "log" . +ipftype ::= "ipf" | "nat" | "state" . + +.fi +.PP +In addition, lines that start with a # are considered to be comments. +.TP +.SH OVERVIEW +.PP +The ipmon configuration file is used for defining rules to be executed when +logging records are read from +.B /dev/ipl. +.PP +At present, only IPv4 matching is available for source/destination address +matching. +.SH MATCHING +.PP +Each rule for ipmon consists of two primary segments: the first describes how +the log record is to be matched, the second defines what action to take if +there is a positive match. All entries of the rules present in the file are +compared for matches - there is no first or last rule match. +.SH FILES +/dev/ipl +.br +/dev/ipf +.br +/dev/ipnat +.br +/dev/ipstate +.br +/etc/ipmon.conf +.SH SEE ALSO +ipmon(8), ipl(4) diff --git a/contrib/ipfilter/man/ipnat.5 b/contrib/ipfilter/man/ipnat.5 index 2bedd0c5f3b4..7db33086eeb8 100644 --- a/contrib/ipfilter/man/ipnat.5 +++ b/contrib/ipfilter/man/ipnat.5 @@ -1,3 +1,5 @@ +.\" $NetBSD$ +.\" .TH IPNAT 5 .SH NAME ipnat, ipnat.conf \- IP NAT file format @@ -7,45 +9,47 @@ The format for files accepted by ipnat is described by the following grammar: .nf ipmap :: = mapblock | redir | map . -map ::= mapit ifname ipmask "->" dstipmask [ mapport ] mapoptions. -map ::= mapit ifname fromto "->" dstipmask [ mapport ] mapoptions. -mapblock ::= "map-block" ifname ipmask "->" ipmask [ ports ] mapoptions. +map ::= mapit ifname lhs "->" dstipmask [ mapicmp | mapport | mapproxy ] + mapoptions . +mapblock ::= "map-block" ifname lhs "->" ipmask [ ports ] mapoptions . redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] rdrport rdroptions . -dport ::= "port" number [ "-" number ] . -ports ::= "ports" number | "auto" . -rdrport ::= "port" number . +lhs ::= ipmask | fromto . +dport ::= "port" portnum [ "-" portnum ] . +ports ::= "ports" numports | "auto" . +rdrport ::= "port" portnum . mapit ::= "map" | "bimap" . fromto ::= "from" object "to" object . ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask . dstipmask ::= ipmask | "range" ip "-" ip . +mapicmp ::= "icmpidmap" "icmp" number ":" number . mapport ::= "portmap" tcpudp portspec . mapoptions ::= [ tcpudp ] [ "frag" ] [ age ] [ clamp ] . -rdroptions ::= [ tcpudp | protocol ] [ rr ] [ "frag" ] [ age ] [ clamp ] . +rdroptions ::= rdrproto [ rr ] [ "frag" ] [ age ] [ clamp ] [ rdrproxy ] . -object :: = addr [ port-comp | port-range ] . -addr :: = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . +object :: = addr [ port-comp | port-range ] . +addr :: = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . port-comp :: = "port" compare port-num . port-range :: = "port" port-num range port-num . +rdrproto ::= tcpudp | protocol . rr ::= "round-robin" . age ::= "age" decnumber [ "/" decnumber ] . clamp ::= "mssclamp" decnumber . -tcpudp ::= "tcp/udp" | "tcp" | "udp" . +tcpudp ::= "tcp/udp" | protocol . +mapproxy ::= "proxy" "port" port proxy-name '/' protocol +rdrproxy ::= "proxy" proxy-name . protocol ::= protocol-name | decnumber . -nummask ::= host-name [ "/" number ] . -portspec ::= "auto" | number ":" number . +nummask ::= host-name [ "/" decnumber ] . +portspec ::= "auto" | portnumber ":" portnumber . +port ::= portnumber | port-name . +portnumber ::= number { numbers } . ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers . -number ::= numbers [ number ] . numbers ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' . .fi .PP -In addition to this, # is used to mark the start of a comment and may -appear at the end of a line with a NAT rule (as described above) or on its -own lines. Blank lines are ignored. -.PP For standard NAT functionality, a rule should start with \fBmap\fP and then proceeds to specify the interface for which outgoing packets will have their source address rewritten. @@ -101,41 +105,12 @@ or as map de0 from 10.1.0.0/16 to any -> 201.2.3.4/32 .fi .LP -For even greater control, one may negate either of the "from" or "to" clauses -with a preceding exclamation mark ("!"). Please note that one may not use a -negated "from" within a \fBmap\fP rule or a negated "to" within a \fBrdr\fP -rule. Such a rule might look like the following: -.LP -.nf -+map de0 from 10.1.0.0/16 ! to 10.1.0.0/16 -> 201.2.3.4/32 -.fi -.PP Only IP address and port numbers can be compared against. This is available with all NAT rules. -.SH COMMAND QUALIFIERS -At the end of each rule, a number of qualifiers can be used to change how -the rule works. They are as follows: -.TP -protocol -A specific protocol may be given either by its name (as found in -/etc/protocols) or its number. A special case for supporting both -TCP and UDP is allowed with the name \fBtcp/udp\fP. -.TP -.B round-robin -Once a rule with this term has been successfully used, it is put at the -bottom of the list of those available so that each one will get used, in -turn, in a list of matching left hand sides. -.TP -.B frag -This qualifier is currently has no impact on NAT operation. -.TP -.B age -If more refined timeouts are required than those available globally for -NAT settings, this allows you to set them for \fBnon-TCP\fP use. .SH TRANSLATION .PP To the right of the "->" is the address and port specification which will be -written into the packet providing it has already successful matched the +written into the packet providing it has already successfully matched the prior constraints. The case of redirections (\fBrdr\fP) is the simplest: the new destination address is that specified in the rule. For \fBmap\fP rules, the destination address will be one for which the tuple combining @@ -149,13 +124,76 @@ the packet will not be translated. The \fBmap-block\fP is more limited in how it searches for a new, free and unique tuple, in that it will used an algorithm to determine what the new source address should be, along with the range of available ports - the IP address is never changed and nor does the -port number ever exceed its alloted range. +port number ever exceed its allotted range. +.SH ICMPIDMAP +.PP +ICMP messages can be divided into two groups: "errors" and "queries". ICMP +errors are generated as a response of another IP packet. IP Filter will take +care that ICMP errors that are the response of a NAT-ed IP packet are +handled properly. +.PP +For 4 types of ICMP queries (echo request, timestamp request, information +request and address mask request) IP Filter supports an additional mapping +called "ICMP id mapping". All these 4 types of ICMP queries use a unique +identifier called the ICMP id. This id is set by the process sending the +ICMP query and it is usually equal to the process id. The receiver of the +ICMP query will use the same id in its response, thus enabling the +sender to recognize that the incoming ICMP reply is intended for him and is +an answer to a query that he made. The "ICMP id mapping" feature modifies +these ICMP id in a way identical to \fBportmap\fP for TCP or UDP. +.PP +The reason that you might want this, is that using this feature you don't +need an IP address per host behind the NAT box, that wants to do ICMP queries. +The two numbers behind the \fBicmpidmap\fP keyword are the first and the +last icmp id number that can be used. There is one important caveat: if you +map to an IP address that belongs to the NAT box itself (notably if you have +only a single public IP address), then you must ensure that the NAT box does +not use the \fBicmpidmap\fP range that you specified in the \fBmap\fP rule. +Since the ICMP id is usually the process id, it is wise to restrict the +largest permittable process id (PID) on your operating system to e.g. 63999 and +use the range 64000:65535 for ICMP id mapping. Changing the maximal PID is +system dependent. For most BSD derived systems can be done by changing +PID_MAX in /usr/include/sys/proc.h and then rebuild the system. .SH KERNEL PROXIES .PP IP Filter comes with a few, simple, proxies built into the code that is loaded into the kernel to allow secondary channels to be opened without forcing the -packets through a user program. -.SH TRNSPARENT PROXIES +packets through a user program. The current state of the proxies is listed +below, as one of three states: +.HP +Aging - protocol is roughly understood from +the time at which the proxy was written but it is not well tested or +maintained; +.HP +Developmental - basic functionality exists, works most of the time but +may be problematic in extended real use; +.HP +Experimental - rough support for the protocol at best, may or may not +work as testing has been at best sporadic, possible large scale changes +to the code in order to properly support the protocol. +.HP +Mature - well tested, protocol is properly +understood by the proxy; +.PP +The currently compiled in proxy list is as follows: +.HP +FTP - Mature +.HP +IRC - Experimental +.HP +rpcbind - Experimental +.HP +H.323 - Experimental +.HP +Real Audio (PNA) - Aging +.HP +IPsec - Developmental +.HP +netbios - Experimental +.HP +R-command - Mature + +.SH TRANSPARENT PROXIES .PP True transparent proxying should be performed using the redirect (\fBrdr\fP) rules directing ports to localhost (127.0.0.1) with the proxy program doing @@ -226,7 +264,13 @@ map ppp0 172.192.0.0/16 -> 209.1.2.0/24 portmap tcp/udp auto .fi .PP which would result in each IP address being given a small range of ports to -use (252). The problem here is that the \fBmap\fP directive tells the NAT +use (252). In all cases, the new port number that is used is deterministic. +That is, port X will always map to port Y. +WARNING: It is not advisable to use the \fBauto\fP feature if you are map'ing +to a /32 (i.e. 0/32) because the NAT code will try to map multiple hosts to +the same port number, outgoing and ultimately this will only succeed for one +of them. +The problem here is that the \fBmap\fP directive tells the NAT code to use the next address/port pair available for an outgoing connection, resulting in no easily discernible relation between external addresses/ports and internal ones. This is overcome by using \fBmap-block\fP as follows: @@ -241,7 +285,6 @@ own. As opposed to the above use of \fBmap\fP, if for some reason the user of (say) 172.192.0.2 wanted 260 simultaneous connections going out, they would be limited to 252 with \fBmap-block\fP but would just \fImove on\fP to the next IP address with the \fBmap\fP command. -.SH FILES /dev/ipnat .br /etc/services diff --git a/contrib/ipfilter/man/ipnat.8 b/contrib/ipfilter/man/ipnat.8 index 3b365ed6bc25..49a09beaf6d6 100644 --- a/contrib/ipfilter/man/ipnat.8 +++ b/contrib/ipfilter/man/ipnat.8 @@ -1,10 +1,18 @@ +.\" $NetBSD$ +.\" .TH IPNAT 8 .SH NAME -ipnat \- user interface to the NAT +ipnat \- user interface to the NAT subsystem .SH SYNOPSIS .B ipnat [ -.B \-lnrsvCF +.B \-dhlnrsvCF +] +[ +.B \-M core +] +[ +.B \-N system ] .B \-f <\fIfilename\fP> .SH DESCRIPTION @@ -16,33 +24,48 @@ Each rule processed by \fBipnat\fP is added to the kernels internal lists if there are no parsing problems. Rules are added to the end of the internal lists, matching the order in which they appear when given to \fBipnat\fP. +.PP +Note that if +\fBipf(8)\fP +is not enabled when NAT is configured, it will be enabled +automatically, as the same kernel facilities are used for +NAT functionality. In addition, packet forwarding must be +enabled. .SH OPTIONS .TP .B \-C delete all entries in the current NAT rule listing (NAT rules) + .TP +.B \-d +Enable printing of some extra debugging information. .TP .B \-F delete all active entries in the current NAT translation table (currently active NAT mappings) .TP +.B \-h +Print number of hits for each MAP/Redirect filter. +.TP .B \-l Show the list of current NAT table entry mappings. .TP .B \-n -This flag (no-change) prevents \fBipnat\fP from actually making any ioctl +This flag (no-change) prevents \fBipf\fP from actually making any ioctl calls or doing anything which would alter the currently running kernel. .TP -.B \-s -Retrieve and display NAT statistics -.TP .B \-r Remove matching NAT rules rather than add them to the internal lists .TP +.B \-s +Retrieve and display NAT statistics +.TP .B \-v Turn verbose mode on. Displays information relating to rule processing and active rules/table entries. .DT .SH FILES /dev/ipnat +.br +/usr/share/examples/ipf Directory with examples. .SH SEE ALSO ipnat(5), ipf(8), ipfstat(8) diff --git a/contrib/ipfilter/man/ippool.5 b/contrib/ipfilter/man/ippool.5 new file mode 100644 index 000000000000..c9eaaca65b19 --- /dev/null +++ b/contrib/ipfilter/man/ippool.5 @@ -0,0 +1,155 @@ +.\" $NetBSD$ +.\" +.TH IPPOOL 5 +.SH NAME +ippool, ippool.conf \- IP Pool file format +.SH DESCRIPTION +The format for files accepted by ippool is described by the following grammar: +.LP +.nf +line ::= table | groupmap . +table ::= "table" role tabletype . +groupmap ::= "group-map" inout role number ipfgroup +tabletype ::= ipftree | ipfhash . + +role ::= "role" "=" "ipf" . +inout ::= "in" | "out" . + +ipftree ::= "type" "=" "tree" number "{" addrlist "}" . +ipfhash ::= "type" "=" "hash" number hashopts "{" hashlist "}" . + +ipfgroup ::= setgroup hashopts "{" grouplist "}" | + hashopts "{" setgrouplist "}" . +setgroup ::= "group" "=" groupname . + +hashopts ::= size [ seed ] | seed . + +size ::= "size" number . +seed ::= "seed" number . + +addrlist ::= [ "!" ] addrmask ";" [ addrlist ] . +grouplist ::= groupentry ";" [ grouplist ] | addrmask ";" [ grouplist ] . + +setgrouplist ::= groupentry ";" [ setgrouplist ] . + +groupentry ::= addrmask "," setgroup . + +hashlist ::= hashentry ";" [ hashlist ] . +hashentry ::= addrmask . + +addrmask ::= ipaddr | ipaddr "/" mask . + +mask ::= number | ipaddr . + +groupname ::= number | name . + +number ::= digit { digit } . + +ipaddr = host-num "." host-num "." host-num "." host-num . +host-num = digit [ digit [ digit ] ] . + +digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" . +name ::= letter { letter | digit } . +.fi +.PP +The IP pool configuration file is used for defining a single object that +contains a reference to multiple IP address/netmask pairs. A pool may consist +of a mixture of netmask sizes, from 0 to 32. +.PP +At this point in time, only IPv4 addressing is supported. +.TP +.SH OVERVIEW +.PP +The IP pool configuration file provides for defining two different mechanisms +for improving speed in matching IP addresses with rules. +The first, +.B table +, defines a lookup +.I table +to provide a single reference in a +filter rule to multiple targets and the second, +.B group-map +, provides a mechanism to target multiple groups from a single filter line. +.PP +The +.B group-map +command can only be used with filter rules that use the +.B call +command to invoke either +.B fr_srcgrpmap +or +.B fr_dstgrpmap +, to use the source or destination address, +respectively, for determining which filter group to jump to next for +continuation of filter packet processing. +.SH POOL TYPES +.PP +Two storage formats are provided: hash tables and tree structure. The hash +table is intended for use with objects all containing the same netmask or a +few different sized netmasks of non-overlapping address space and the tree +is designed for being able to support exceptions to a covering mask, in +addition to normal searching as you would do with a table. It is not possible +to use the tree data storage type with +.B group-map +configuration entries. +.SH POOL ROLES +.PP +When a pool is defined in the configruation file, it must have an associated +role. At present the only supported role is +.B ipf. +Future development will see futher expansion of their use by other sections +of IPFilter code. +.SH EXAMPLES +The following examples show how the pool configuration file is used with +the ipf configuration file to enhance the ability for the ipf configuration +file to be succinct in meaning. +.TP +1 +The first example shows how a filter rule makes reference to a specific +pool for matching of the source address. +.nf +pass in from pool/100 to any +.fi +.PP +The pool configuration, which matches IP addresses 1.1.1.1 and any +in 2.2.0.0/16, except for those in 2.2.2.0/24. +.PP +.nf +table role = ipf type = tree number = 100 + { 1.1.1.1/32; 2.2.0.0/16; !2.2.2.0/24 }; +.fi +.TP +2 +The following ipf.conf extract uses the +fr_srcgrpmap/fr_dstgrpmap lookups to use the +.B group-map +facility to lookup the next group to use for filter processing, providing +the +.B call +filter rule is matched. +.nf +call now fr_srcgrpmap/1010 in all +call now fr_dstgrpmap/2010 out all +pass in all group 1020 +block in all group 1030 +pass out all group 2020 +block out all group 2040 +.fi +.PP +A ippool configuration to work with the above ipf.conf file might +look like this: +.PP +.nf +group-map in role = ipf number = 1010 + { 1.1.1.1/32, group = 1020; 3.3.0.0/16, group = 1030; }; +group-map out role = ipf number = 2010 group = 2020 + { 2.2.2.2/32; 4.4.0.0/16; 5.0.0.0/8, group = 2040; }; +.fi +.SH FILES +/dev/iplookup +.br +/etc/ippool.conf +.br +/etc/hosts +.SH SEE ALSO +ippool(8), hosts(5), ipf(5), ipf(8), ipnat(8) diff --git a/contrib/ipfilter/man/ippool.8 b/contrib/ipfilter/man/ippool.8 new file mode 100644 index 000000000000..6ed1e8841603 --- /dev/null +++ b/contrib/ipfilter/man/ippool.8 @@ -0,0 +1,126 @@ +.\" $NetBSD$ +.\" +.TH IPPOOL 8 +.SH NAME +ippool \- user interface to the IPFilter pools +.SH SYNOPSIS +.br +.B ippool +-a [-dnv] [-m ] [-o ] -i [/] +.br +.B ippool +-A [-dnv] [-m ] [-o ] [-S ] [-t ] +.br +.B ippool +-f [-dnuv] +.br +.B ippool +-F [-dv] [-o ] [-t ] +.br +.B ippool +-l [-dv] [-m ] [-t ] +.br +.B ippool +-r [-dnv] [-m ] [-o ] -i [/] +.br +.B ippool +-R [-dnv] [-m ] [-o ] [-t ] +.br +.B ippool +-s [-dtv] [-M ] [-N ] +.SH DESCRIPTION +.PP +.B Ippool +is used to manage information stored in the IP pools subsystem of IPFilter. +Configuration file information may be parsed and loaded into the kernel, +currently configured pools removed or changed as well as inspected. +.PP +The command line options used are broken into two sections: the global +options and the instance specific options. +.SH GLOBAL OPTIONS +.TP +.B \-d +Toggle debugging of processing the configuration file. +.TP +.B \-n +This flag (no-change) prevents +.B ippool +from actually making any ioctl +calls or doing anything which would alter the currently running kernel. +.TP +.B \-v +Turn verbose mode on. +.SH COMMAND OPTIONS +.TP +.B -a +Add a new data node to an existing pool in the kernel. +.TP +.B -A +Add a new (empty) pool to the kernel. +.TP +.B -f +Read in IP pool configuration information from the file and load it into +the kernel. +.TP +.B -F +Flush loaded pools from the kernel. +.TP +.B -l +Display a list of pools currently loaded into the kernel. +.TP +.B -r +Remove an existing data node from a pool in the kernel. +.TP +.B -R +Remove an existing pool from within the kernel. +.TP +.B -s +Display IP pool statistical information. +.SH OPTIONS +.TP +.B -i [/] +Sets the IP address for the operation being undertaken with an +all-one's mask or, optionally, a specific netmask given in either +the dotted-quad notation or a single integer. +.TP +.B -m +Sets the pool name for the current operation. +.TP +.B -M +Specify an alternative path to /dev/kmem to retrieve statistical information +from. +.TP +.B -N +Specify an alternative path to lookup symbol name information from when +retrieving statistical information. +.TP +.B -o +Sets the role with which this pool is to be used. Currently only +.B ipf, +.B auth +and +.B count +are accepted as arguments to this option. +.TP +.B -S +Sets the hashing seed to the number specified. Only for use with +.B hash +type pools. +.TP +.B -t +Sets the type of pool being defined. Myst be one of +.B tree, +.B hash, +.B group-map. +.TP +.B -u +When parsing a configuration file, rather than load new pool data into the +kernel, unload it. +.DT +.SH FILES +.br +/dev/iplookup +.br +/etc/ippool.conf +.SH SEE ALSO +ippool(5), ipf(8), ipfstat(8) diff --git a/contrib/ipfilter/man/ipscan.5 b/contrib/ipfilter/man/ipscan.5 new file mode 100644 index 000000000000..4a001749e863 --- /dev/null +++ b/contrib/ipfilter/man/ipscan.5 @@ -0,0 +1,52 @@ +.\" $NetBSD$ +.\" +.TH IPSCAN 5 +.SH NAME +ipscan, ipscan.conf \- ipscan file format +.SH DESCRIPTION +.PP +WARNING: This feature is to be considered experimental and may change +significantly until a final implementation is drawn up. +.PP +The format for files accept by ipscan currently follow this rough grammar: +.LP +.nf +line ::= name ":" matchup [ "," matchup ] "=" action . +matchup ::= "(" ")" | "(" literal ")" | "(" literal "," match ")" . +action ::= result | result "else" result . +result ::= "close" | "track" | redirect . +redirect ::= "redirect" ip-address [ "(" "," port-number ")" ] . +match ::= { match-char } +match-char ::= "*" | "?" | "." +.fi +.PP +In this example an ip-address is a dotted-quad IPv4 address and a port-number +is a number betwee 1 and 65535, inclusive. The match string is must be of +same length as the literal string that it is matching (literal). The length +of either string is limited to 16 bytes. +.PP +Currently, the redirect option is not yet been implemented. +.LP +.nf +# +# * = match any character, . = exact match, ? = case insensitive +# +# Scan for anything that looks like HTTP and redirect it to the local +# proxy. One catch - this feature (redirect) is not yet implemented. +# +http : ("GET ", "???." ) = redirect(127.0.0.1) +# +# Track ssh connections (i.e do nothing) +# +ssh : (), ("SSH-") = track +# +# Things which look like smtp to be tracked else closed. +# Client can start with EHLO (ESMTP) or HELO (SMTP). +# +smtp : ("HELO ", "**??."), ("220 ", "....") = track else close +# +.fi +.SH FILES +/etc/ipscan.conf +.SH SEE ALSO +ipscan(8) diff --git a/contrib/ipfilter/man/ipscan.8 b/contrib/ipfilter/man/ipscan.8 new file mode 100644 index 000000000000..d3ce9528734d --- /dev/null +++ b/contrib/ipfilter/man/ipscan.8 @@ -0,0 +1,44 @@ +.\" $NetBSD$ +.\" +.TH IPSCAN 8 +.SH NAME +ipscan \- user interface to the IPFilter content scanning +.SH SYNOPSIS +.B ipscan +[ +.B \-dlnrsv +] [ +] +.B \-f <\fIfilename\fP> +.SH DESCRIPTION +.PP +\fBipscan\fP opens the filename given (treating "\-" as stdin) and parses the +file to build up a content scanning configuration to load into the kernel. +Currently only the first 16 bytes of a connection can be compared. +.SH OPTIONS +.TP +.B \-d +Toggle debugging of processing the configuration file. +.TP +.B \-l +Show the list of currently configured content scanning entries. +.TP +.B \-n +This flag (no-change) prevents \fBipscan\fP from actually making any ioctl +calls or doing anything which would alter the currently running kernel. +.TP +.B \-r +Remove commands from kernel configuration as they are read from the +configuration file rather than adding new ones. +.TP +.B \-s +Retrieve and display content scanning statistics +.TP +.B \-v +Turn verbose mode on. +.DT +.SH FILES +/dev/ipscan +/etc/ipscan.conf +.SH SEE ALSO +ipscan(5), ipf(8) diff --git a/contrib/ipfilter/man/mkfilters.1 b/contrib/ipfilter/man/mkfilters.1 index b5fd9dc59f36..3bac7d16bb5d 100644 --- a/contrib/ipfilter/man/mkfilters.1 +++ b/contrib/ipfilter/man/mkfilters.1 @@ -1,3 +1,5 @@ +.\" $NetBSD$ +.\" .TH MKFILTERS 1 .SH NAME mkfilters \- generate a minimal firewall ruleset for ipfilter diff --git a/contrib/ipfilter/md5.c b/contrib/ipfilter/md5.c new file mode 100644 index 000000000000..78a0eb720ae7 --- /dev/null +++ b/contrib/ipfilter/md5.c @@ -0,0 +1,314 @@ +/* $NetBSD$ */ + + + +/* + *********************************************************************** + ** md5.c -- the source code for MD5 routines ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#if defined(_KERNEL) && !defined(__sgi) +# include +#else +# include +#endif + +#include "md5.h" + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** + */ + +/* forward declaration */ +static void Transform __P((UINT4 *, UINT4 *)); + +static unsigned char PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#ifdef __STDC__ +#define UL(x) x##U +#else +#define UL(x) x +#endif + +/* The routine MD5Init initializes the message-digest context + mdContext. All fields are set to zero. + */ +void MD5Init (mdContext) +MD5_CTX *mdContext; +{ + mdContext->i[0] = mdContext->i[1] = (UINT4)0; + + /* Load magic initialization constants. + */ + mdContext->buf[0] = (UINT4)0x67452301; + mdContext->buf[1] = (UINT4)0xefcdab89; + mdContext->buf[2] = (UINT4)0x98badcfe; + mdContext->buf[3] = (UINT4)0x10325476; +} + +/* The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. + */ +void MD5Update (mdContext, inBuf, inLen) +MD5_CTX *mdContext; +unsigned char *inBuf; +unsigned int inLen; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* update number of bits */ + if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) + mdContext->i[1]++; + mdContext->i[0] += ((UINT4)inLen << 3); + mdContext->i[1] += ((UINT4)inLen >> 29); + + while (inLen--) { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +/* The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. + */ +void MD5Final (hash, mdContext) +unsigned char hash[]; +MD5_CTX *mdContext; +{ + UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5Update (mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) + in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | + (((UINT4)mdContext->in[ii+2]) << 16) | + (((UINT4)mdContext->in[ii+1]) << 8) | + ((UINT4)mdContext->in[ii]); + Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } + bcopy((char *)mdContext->digest, (char *)hash, 16); +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void Transform (buf, in) +UINT4 *buf; +UINT4 *in; +{ + UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ + FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ + FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ + FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ + FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ + FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ + FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ + FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ + GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ + GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ + GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ + GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ + GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ + GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ + HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ + HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ + HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ + HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ + HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ + HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ + II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ + II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ + II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ + II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ + II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ + II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ + II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ + II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ + II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ + II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ + II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ + II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ + II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ + II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ + II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + *********************************************************************** + ** End of md5.c ** + ******************************** (cut) ******************************** + */ diff --git a/contrib/ipfilter/md5.h b/contrib/ipfilter/md5.h new file mode 100644 index 000000000000..40e8dc65a89c --- /dev/null +++ b/contrib/ipfilter/md5.h @@ -0,0 +1,72 @@ +/* $NetBSD$ */ + +/* + *********************************************************************** + ** md5.h -- header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#ifndef __MD5_INCLUDE__ + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif +#ifndef __STDC__ +# undef const +# define const +#endif + +/* typedef a 32-bit type */ +typedef unsigned int UINT4; + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ + UINT4 buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +extern void MD5Init __P((MD5_CTX *)); +extern void MD5Update __P((MD5_CTX *, unsigned char *, unsigned int)); +extern void MD5Final __P((unsigned char *, MD5_CTX *)); + +#define __MD5_INCLUDE__ +#endif /* __MD5_INCLUDE__ */ diff --git a/contrib/ipfilter/mlf_ipl.c b/contrib/ipfilter/mlf_ipl.c index a165c792cde4..c0cdce825a31 100644 --- a/contrib/ipfilter/mlf_ipl.c +++ b/contrib/ipfilter/mlf_ipl.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1993-2001 by Darren Reed. * @@ -11,16 +13,22 @@ #include -#if defined(__FreeBSD__) -# ifndef __FreeBSD_version -# ifdef IPFILTER_LKM +#ifdef IPFILTER_LKM +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 # include -# else -# include # endif # endif -# ifdef IPFILTER_LKM -# define ACTUALLY_LKM_NOT_KERNEL +# define ACTUALLY_LKM_NOT_KERNEL +#else +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 +# include +# endif # endif #endif #include @@ -41,7 +49,6 @@ #endif #include #include -#include #include #include #include @@ -60,7 +67,6 @@ #include #include #include -#include #include #include #include @@ -73,68 +79,65 @@ #include "netinet/ip_nat.h" #include "netinet/ip_auth.h" #include "netinet/ip_frag.h" -#include "netinet/ip_proxy.h" #if !defined(VOP_LEASE) && defined(LEASE_CHECK) #define VOP_LEASE LEASE_CHECK #endif -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - int xxxinit __P((struct lkm_table *, int, int)); -#ifdef SYSCTL_INT +#ifdef SYSCTL_OID +int sysctl_ipf_int SYSCTL_HANDLER_ARGS; +# define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ + ptr, val, sysctl_ipf_int, "I", descr); +# define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ +# define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW, - &fr_minttllog, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, &fr_tcpidletimeout, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, &fr_tcphalfclosed, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, &fr_tcpclosewait, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, &fr_tcplastack, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, &fr_tcptimeout, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, &fr_tcpclosed, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, &fr_udptimeout, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RW, - &fr_udpacktimeout, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, &fr_icmptimeout, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmpacktimeout, CTLFLAG_RW, - &fr_icmpacktimeout, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, &fr_defnatage, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, &fr_ipfrttl, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW, - &ipl_unreach, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, &fr_running, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, + &fr_statesize, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, + &fr_statemax, 0, ""); +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, &fr_authsize, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, &fr_authused, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, &fr_defaultauthage, 0, ""); -SYSCTL_INT(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, +SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, &ippr_ftp_pasvonly, 0, ""); #endif #ifdef DEVFS -static void *ipf_devfs[IPL_LOGMAX + 1]; +static void *ipf_devfs[IPL_LOGSIZE]; #endif #if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) @@ -142,17 +145,17 @@ int ipl_major = 0; static struct cdevsw ipldevsw = { - iplopen, /* open */ - iplclose, /* close */ - iplread, /* read */ - (void *)nullop, /* write */ - iplioctl, /* ioctl */ - (void *)nullop, /* stop */ - (void *)nullop, /* reset */ - (void *)NULL, /* tty */ - (void *)nullop, /* select */ - (void *)nullop, /* mmap */ - NULL /* strategy */ + iplopen, /* open */ + iplclose, /* close */ + iplread, /* read */ + (void *)nullop, /* write */ + iplioctl, /* ioctl */ + (void *)nullop, /* stop */ + (void *)nullop, /* reset */ + (void *)NULL, /* tty */ + (void *)nullop, /* select */ + (void *)nullop, /* mmap */ + NULL /* strategy */ }; MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); @@ -183,7 +186,8 @@ static int if_ipl_remove __P((void)); static int ipl_major = CDEV_MAJOR; static int iplaction __P((struct lkm_table *, int)); -static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, NULL }; +static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, + IPL_SCAN, IPL_SYNC, IPL_POOL, NULL }; extern int lkmenodev __P((void)); @@ -236,6 +240,12 @@ int cmd; devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]); if (ipf_devfs[IPL_LOGAUTH]) devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]); + if (ipf_devfs[IPL_LOGSCAN]) + devfs_remove_dev(ipf_devfs[IPL_LOGSCAN]); + if (ipf_devfs[IPL_LOGSYNC]) + devfs_remove_dev(ipf_devfs[IPL_LOGSYNC]); + if (ipf_devfs[IPL_LOGLOOKUP]) + devfs_remove_dev(ipf_devfs[IPL_LOGLOOKUP]); #endif } return err; @@ -329,7 +339,7 @@ int cmd; VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); #if (__FreeBSD_version >= 300000) - vput(nd.ni_dvp); + vput(nd.ni_dvp); #endif if (error) return error; @@ -346,11 +356,11 @@ int cmd; size_t strlen(string) char *string; { - register char *s; + register char *s; - for (s = string; *s; s++) + for (s = string; *s; s++) ; - return (size_t)(s - string); + return (size_t)(s - string); } @@ -395,7 +405,7 @@ int cmd, ver; # endif } # endif /* IPFILTER_LKM */ -static int ipl_devsw_installed = 0; +static ipl_devsw_installed = 0; static void ipl_drvinit __P((void *unused)) { @@ -415,15 +425,43 @@ static void ipl_drvinit __P((void *unused)) tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT, DV_CHR, 0, 0, 0600, "ipnat"); tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE, - DV_CHR, 0, 0, 0600, + DV_CHR, 0, 0, 0600, "ipstate"); tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH, - DV_CHR, 0, 0, 0600, + DV_CHR, 0, 0, 0600, "ipauth"); # endif } } + +#ifdef SYSCTL_IPF +int +sysctl_ipf_int SYSCTL_HANDLER_ARGS +{ + int error = 0; + + if (arg1) + error = SYSCTL_OUT(req, arg1, sizeof(int)); + else + error = SYSCTL_OUT(req, &arg2, sizeof(int)); + + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else { + if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0)) + error = EBUSY; + else + error = SYSCTL_IN(req, arg1, sizeof(int)); + } + return (error); +} +#endif + + # if defined(IPFILTER_LKM) || \ defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL) diff --git a/contrib/ipfilter/mlf_rule.c b/contrib/ipfilter/mlf_rule.c new file mode 100644 index 000000000000..731ef5e439c4 --- /dev/null +++ b/contrib/ipfilter/mlf_rule.c @@ -0,0 +1,168 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +/* + * 29/12/94 Added code from Marc Huber to allow it to allocate + * its own major char number! Way cool patch! + */ + + +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ > 1) +# ifdef IPFILTER_LKM +# include +# define ACTUALLY_LKM_NOT_KERNEL +# else +# include +# endif +#endif +#include +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) +# include +# include +# ifdef DEVFS +# include +# endif /*DEVFS*/ +#endif +#include +#include +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if BSD >= 199506 +# include +#endif +#if (__FreeBSD_version >= 300000) +# include +#endif +#if (__FreeBSD_version >= 199511) +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#if (__FreeBSD__ > 1) +# include +#endif +#include +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_rules.h" + + +int xxxinit __P((struct lkm_table *, int, int)); + +#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) +MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); +#endif + +static int ipfrule_ioctl __P((struct lkm_table *, int)); + +#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) + +int xxxinit(lkmtp, cmd, ver) +struct lkm_table *lkmtp; +int cmd, ver; +{ + DISPATCH(lkmtp, cmd, ver, ipfrule_ioctl, ipfrule_ioctl, ipfrule_ioctl); +} +#else /* __FREEBSD_version >= 220000 */ +# ifdef IPFILTER_LKM +# include + +# if (__FreeBSD_version >= 300000) +MOD_MISC(ipfrule); +# else +MOD_DECL(ipfrule); + + +static struct lkm_misc _module = { + LM_MISC, + LKM_VERSION, + "IP Filter rules", + 0, +}; +# endif + + +int ipfrule __P((struct lkm_table *, int, int)); + + +int ipfrule(lkmtp, cmd, ver) +struct lkm_table *lkmtp; +int cmd, ver; +{ +# if (__FreeBSD_version >= 300000) + MOD_DISPATCH(ipfrule, lkmtp, cmd, ver, ipfrule_ioctl, ipfrule_ioctl, + ipfrule_ioctl); +# else + DISPATCH(lkmtp, cmd, ver, ipfrule_ioctl, ipfrule_ioctl, ipfrule_ioctl); +# endif +} +# endif /* IPFILTER_LKM */ + + +int ipfrule_load(lkmtp, cmd) +struct lkm_table *lkmtp; +int cmd; +{ + return ipfrule_add(); +} + + +int ipfrule_unload(lkmtp, cmd) +struct lkm_table *lkmtp; +int cmd; +{ + return ipfrule_remove(); +} + + +static int ipfrule_ioctl(lkmtp, cmd) +struct lkm_table *lkmtp; +int cmd; +{ + int err = 0; + + switch (cmd) + { + case LKM_E_LOAD : + if (lkmexists(lkmtp)) + return EEXIST; + + err = ipfrule_load(lkmtp, cmd); + if (!err) + fr_refcnt++; + break; + case LKM_E_UNLOAD : + err = ipfrule_unload(lkmtp, cmd); + if (!err) + fr_refcnt--; + break; + case LKM_E_STAT : + break; + default: + err = EIO; + break; + } + return err; +} +#endif /* _FreeBSD_version */ diff --git a/contrib/ipfilter/mlfk_rule.c b/contrib/ipfilter/mlfk_rule.c new file mode 100644 index 000000000000..a4f3ba71ff22 --- /dev/null +++ b/contrib/ipfilter/mlfk_rule.c @@ -0,0 +1,69 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2000 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: mlfk_rule.c,v 2.4.4.2 2004/04/16 23:32:08 darrenr Exp + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ip_rules.h" + + +static int +ipfrule_modevent(module_t mod, int type, void *unused) +{ + int error = 0; + + switch (type) + { + case MOD_LOAD : + error = ipfrule_add(); + if (!error) + fr_refcnt++; + break; + case MOD_UNLOAD : + error = ipfrule_remove(); + if (!error) + fr_refcnt--; + break; + default: + error = EINVAL; + break; + } + return error; +} + +static moduledata_t ipfrulemod = { + "ipfrule", + ipfrule_modevent, + 0 +}; +DECLARE_MODULE(ipfrule, ipfrulemod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); +#ifdef MODULE_DEPEND +MODULE_DEPEND(ipfrule, ipfilter, 1, 1, 1); +#endif +#ifdef MODULE_VERSION +MODULE_VERSION(ipfrule, 1); +#endif diff --git a/contrib/ipfilter/mlh_rule.c b/contrib/ipfilter/mlh_rule.c new file mode 100644 index 000000000000..e71c7be1c0b7 --- /dev/null +++ b/contrib/ipfilter/mlh_rule.c @@ -0,0 +1,114 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-1998 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ +/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ + +/*typedef unsigned int spustate_t;*/ +struct uio; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_rules.h" + + +/* + * Driver Header + */ +static drv_info_t ipf_drv_info = { + "IP Filter Rules", /* type */ + "pseudo", /* class */ + DRV_PSEUDO|DRV_SAVE_CONF|DRV_MP_SAFE, /* flags */ + -1, /* b_major */ + -1, /* c_major */ + NULL, /* cdio */ + NULL, /* gio_private */ + NULL, /* cdio_private */ +}; + + +extern struct mod_operations gio_mod_ops; +static drv_info_t ipf_drv_info; +extern struct mod_conf_data ipf_conf_data; + +static struct mod_type_data ipf_drv_link = { + IPL_VERSION, (void *)NULL +}; + +static struct modlink ipf_mod_link[] = { + { &gio_mod_ops, (void *)&ipf_drv_link }, + { NULL, (void *)NULL } +}; + +struct modwrapper ipf_wrapper = { + MODREV, + ipf_load, + ipf_unload, + (void (*)())NULL, + (void *)&ipf_conf_data, + ipf_mod_link +}; + + +static int ipf_load(void *arg) +{ + int i; + + i = ipfrule_add(); + if (!i) + fr_refcnt--; +#ifdef IPFDEBUG + printf("IP Filter Rules: ipfrule_add() = %d\n", i); +#endif + if (!i) + cmn_err(CE_CONT, "IP Filter Rules: Loaded\n"); + return i; +} + + +static int ipf_unload(void *arg) +{ + int i; + + i = ipfrule_remove(); + if (!i) + fr_refcnt--; +#ifdef IPFDEBUG + printf("IP Filter Rules: ipfrule_remove() = %d\n", i); +#endif + if (!i) + cmn_err(CE_CONT, "IP Filter Rules: Unloaded\n"); + return i; +} diff --git a/contrib/ipfilter/net/.cvsignore b/contrib/ipfilter/net/.cvsignore new file mode 100644 index 000000000000..19f86f493ab1 --- /dev/null +++ b/contrib/ipfilter/net/.cvsignore @@ -0,0 +1 @@ +done diff --git a/contrib/ipfilter/opts.h b/contrib/ipfilter/opts.h new file mode 100644 index 000000000000..602c4e389222 --- /dev/null +++ b/contrib/ipfilter/opts.h @@ -0,0 +1,67 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2000 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Id: opts.h,v 2.12 2003/08/14 14:24:27 darrenr Exp + */ + +#ifndef __OPTS_H__ +#define __OPTS_H__ + +#ifndef SOLARIS +#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) +#endif +#define OPT_REMOVE 0x000001 +#define OPT_DEBUG 0x000002 +#define OPT_AUTHSTATS 0x000004 +#define OPT_RAW 0x000008 +#define OPT_LOG 0x000010 +#define OPT_SHOWLIST 0x000020 +#define OPT_VERBOSE 0x000040 +#define OPT_DONOTHING 0x000080 +#define OPT_HITS 0x000100 +#define OPT_BRIEF 0x000200 +#define OPT_ACCNT 0x000400 +#define OPT_FRSTATES 0x000800 +#define OPT_SHOWLINENO 0x001000 +#define OPT_PRINTFR 0x002000 +#define OPT_OUTQUE FR_OUTQUE /* 0x4000 */ +#define OPT_INQUE FR_INQUE /* 0x8000 */ +#define OPT_ZERORULEST 0x010000 +#define OPT_SAVEOUT 0x020000 +#define OPT_IPSTATES 0x040000 +#define OPT_INACTIVE 0x080000 +#define OPT_NAT 0x100000 +#define OPT_GROUPS 0x200000 +#define OPT_STATETOP 0x400000 +#define OPT_FLUSH 0x800000 +#define OPT_CLEAR 0x1000000 +#define OPT_HEX 0x2000000 +#define OPT_ASCII 0x4000000 +#define OPT_NORESOLVE 0x8000000 + +#define OPT_STAT OPT_FRSTATES +#define OPT_LIST OPT_SHOWLIST + + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +#if defined(sun) && !SOLARIS +# define STRERROR(x) sys_errlist[x] +extern char *sys_errlist[]; +#else +# define STRERROR(x) strerror(x) +#endif + +extern int opts; + +#endif /* __OPTS_H__ */ diff --git a/contrib/ipfilter/pcap-ipf.h b/contrib/ipfilter/pcap-ipf.h new file mode 100644 index 000000000000..a6b974c5413f --- /dev/null +++ b/contrib/ipfilter/pcap-ipf.h @@ -0,0 +1,35 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + */ +/* + * This header file is constructed to match the version described by + * PCAP_VERSION_MAJ. + * + * The structure largely derives from libpcap which wouldn't include + * nicely without bpf. + */ +typedef struct pcap_filehdr { + u_int pc_id; + u_short pc_v_maj; + u_short pc_v_min; + u_int pc_zone; + u_int pc_sigfigs; + u_int pc_slen; + u_int pc_type; +} pcaphdr_t; + +#define TCPDUMP_MAGIC 0xa1b2c3d4 + +#define PCAP_VERSION_MAJ 2 + +typedef struct pcap_pkthdr { + struct timeval ph_ts; + u_int ph_clen; + u_int ph_len; +} pcappkt_t; + diff --git a/contrib/ipfilter/perl/ipf-mrtg.pl b/contrib/ipfilter/perl/ipf-mrtg.pl index cce30ab09c5b..a96a7cddb2b3 100644 --- a/contrib/ipfilter/perl/ipf-mrtg.pl +++ b/contrib/ipfilter/perl/ipf-mrtg.pl @@ -19,4 +19,4 @@ print "$in_pkts\n", my $uptime = `/usr/bin/uptime`; $uptime =~ /^\s+(\d{1,2}:\d{2}..)\s+up\s+(\d+)\s+(......),/; print "$2 $3\n", - "$firewall\n"; \ No newline at end of file + "$firewall\n"; diff --git a/contrib/ipfilter/perl/ipfmeta.pl b/contrib/ipfilter/perl/ipfmeta.pl new file mode 100644 index 000000000000..1a7bb3f1a0e7 --- /dev/null +++ b/contrib/ipfilter/perl/ipfmeta.pl @@ -0,0 +1,210 @@ +#!/usr/bin/perl -w +# +# Written by Camiel Dobbelaar , Aug-2000 +# ipfmeta is in the Public Domain. +# + +use strict; +use Getopt::Std; + +## PROCESS COMMANDLINE +our($opt_v); $opt_v=1; +getopts('v:') || die "usage: ipfmeta [-v verboselevel] [objfile]\n"; +my $verbose = $opt_v + 0; +my $objfile = shift || "ipf.objs"; +my $MAXRECURSION = 10; + +## READ OBJECTS +open(FH, "$objfile") || die "cannot open $objfile: $!\n"; +my @tokens; +while () { + chomp; + s/#.*$//; # remove comments + s/^\s+//; # compress whitespace + s/\s+$//; + next if m/^$/; # skip empty lines + push (@tokens, split); +} +close(FH) || die "cannot close $objfile: $!\n"; +# link objects with their values +my $obj=""; +my %objs; +while (@tokens) { + my $token = shift(@tokens); + if ($token =~ m/^\[([^]]*)\]$/) { + # new object + $obj = $1; + } else { + # new value + push(@{$objs{$obj}}, $token) unless ($obj eq ""); + } +} + +# sort objects: longest first +my @objs = sort { length($b) <=> length($a) } keys %objs; + +## SUBSTITUTE OBJECTS WITH THEIR VALUES FROM STDIN +foreach () { + foreach (expand($_, 0)) { + print; + } +} + +## END + +sub expand { + my $line = shift; + my $level = shift; + my @retlines = $line; + my $obj; + my $val; + + # coarse protection + if ($level > $MAXRECURSION) { + print STDERR "ERR: recursion exceeds $MAXRECURSION levels\n"; + return; + } + + foreach $obj (@objs) { + if ($line =~ m/$obj/) { + @retlines = ""; + if ($level < $verbose) { + # add metarule as a comment + push(@retlines, "# ".$line); + } + foreach $val (@{$objs{$obj}}) { + my $newline = $line; + $newline =~ s/$obj/$val/; + push(@retlines, expand($newline, $level+1)); + } + last; + } + } + + return @retlines; +} + +__END__ + +=head1 NAME + +B - use objects in IP filter files + +=head1 SYNOPSIS + +B [F] [F] + +=head1 DESCRIPTION + +B is used to simplify the maintenance of your IP filter +ruleset. It does this through the use of 'objects'. A matching +object gets replaced by its values at runtime. This is similar to +what a macro processor like m4 does. + +B is specifically geared towards IP filter. It is line +oriented, if an object has multiple values, the line with the object +is duplicated and substituted for each value. It is also recursive, +an object may have another object as a value. + +Rules to be processed are read from stdin, output goes to stdout. + +The verbose option allows for the inclusion of the metarules in the +output as comments. + +Definition of the objects and their values is done in a separate +file, the filename defaults to F. An object is delimited +by square brackets. A value is delimited by whitespace. Comments +start with '#' and end with a newline. Empty lines and extraneous +whitespace are allowed. A value belongs to the first object that +precedes it. + +It is recommended that you use all caps or another distinguishing +feature for object names. You can use B for NAT rules also, +for instance to keep them in sync with filter rules. Combine +B with a Makefile to save typing. + +=head1 OPTIONS + +=over 4 + +=item B<-v> I + +Include metarules in output as comments. Default is 1, the top level +metarules. Higher levels cause expanded metarules to be included. +Level 0 does not add comments at all. + +=back + +=head1 BUGS + +A value can not have whitespace in it. + +=head1 EXAMPLE + +(this does not look good, formatted) + +I + +[PRIVATE] 10.0.0.0/8 127.0.0.0/8 172.16.0.0/12 192.168.0.0/16 + +[MULTICAST] 224.0.0.0/4 + +[UNWANTED] PRIVATE MULTICAST + +[NOC] xxx.yy.zz.1/32 xxx.yy.zz.2/32 + +[WEBSERVERS] 192.168.1.1/32 192.168.1.2/32 + +[MGMT-PORTS] 22 23 + +I + +block in from UNWANTED to any + +pass in from NOC to WEBSERVERS port = MGMT-PORTS + +pass out all + +I + +ipfmeta ipf.objs ipf.rules + +I + +# block in from UNWANTED to any + +block in from 10.0.0.0/8 to any + +block in from 127.0.0.0/8 to any + +block in from 172.16.0.0/12 to any + +block in from 192.168.0.0/16 to any + +block in from 224.0.0.0/4 to any + +# pass in from NOC to WEBSERVERS port = MGMT-PORTS + +pass in from xxx.yy.zz.1/32 to 192.168.1.1/32 port = 22 + +pass in from xxx.yy.zz.1/32 to 192.168.1.1/32 port = 23 + +pass in from xxx.yy.zz.1/32 to 192.168.1.2/32 port = 22 + +pass in from xxx.yy.zz.1/32 to 192.168.1.2/32 port = 23 + +pass in from xxx.yy.zz.2/32 to 192.168.1.1/32 port = 22 + +pass in from xxx.yy.zz.2/32 to 192.168.1.1/32 port = 23 + +pass in from xxx.yy.zz.2/32 to 192.168.1.2/32 port = 22 + +pass in from xxx.yy.zz.2/32 to 192.168.1.2/32 port = 23 + +pass out all + +=head1 AUTHOR + +Camiel Dobbelaar . B is in the Public Domain. + +=cut diff --git a/contrib/ipfilter/perl/logfilter.pl b/contrib/ipfilter/perl/logfilter.pl index 6ebe401ab4ee..a75eafd72e9c 100644 --- a/contrib/ipfilter/perl/logfilter.pl +++ b/contrib/ipfilter/perl/logfilter.pl @@ -178,4 +178,4 @@ tcp 6667 irc.log tcp 7070 realaudio.log tcp 8080 http.log tcp 12345 netbus.log -udp 31337 backorifice.log \ No newline at end of file +udp 31337 backorifice.log diff --git a/contrib/ipfilter/radix.c b/contrib/ipfilter/radix.c new file mode 100644 index 000000000000..964c10952687 --- /dev/null +++ b/contrib/ipfilter/radix.c @@ -0,0 +1,1202 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1988, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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. + * + * @(#)radix.c 8.6 (Berkeley) 10/17/95 + */ + +/* + * Routines to build and maintain radix trees for routing lookups. + */ +#if defined(KERNEL) || defined(_KERNEL) +# undef KERNEL +# undef _KERNEL +# define KERNEL 1 +# define _KERNEL 1 +#endif +#define __SYS_ATOMIC_OPS_H__ +#if !defined(__svr4__) && !defined(__SVR4) && !defined(__osf__) && \ + !defined(__hpux) && !defined(__sgi) +#include +#endif +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif +#ifdef __osf__ +# define CONST +# define _IPV6_SWTAB_H +# define _PROTO_NET_H_ +# define _PROTO_IPV6_H +# include +#endif + +#include +#ifdef _KERNEL +#include +#else +void panic __P((char *str)); +#include +#include +#include +#include +#endif +#ifdef __hpux +#include +#else +#include +#endif +#include +#include +#include +#include +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +/* END OF INCLUDES */ +#include "radix_ipf.h" +#ifndef min +# define min MIN +#endif +#ifndef max +# define max MAX +#endif + +int max_keylen = 16; +static struct radix_mask *rn_mkfreelist; +static struct radix_node_head *mask_rnhead; +static char *addmask_key; +static u_char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; +static char *rn_zeros = NULL, *rn_ones = NULL; + +#define rn_masktop (mask_rnhead->rnh_treetop) +#undef Bcmp +#define Bcmp(a, b, l) (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l)) + +static int rn_satisfies_leaf __P((char *, struct radix_node *, int)); +static int rn_lexobetter __P((void *, void *)); +static struct radix_mask *rn_new_radix_mask __P((struct radix_node *, + struct radix_mask *)); +static int rn_freenode __P((struct radix_node *, void *)); + +/* + * The data structure for the keys is a radix tree with one way + * branching removed. The index rn_b at an internal node n represents a bit + * position to be tested. The tree is arranged so that all descendants + * of a node n have keys whose bits all agree up to position rn_b - 1. + * (We say the index of n is rn_b.) + * + * There is at least one descendant which has a one bit at position rn_b, + * and at least one with a zero there. + * + * A route is determined by a pair of key and mask. We require that the + * bit-wise logical and of the key and mask to be the key. + * We define the index of a route to associated with the mask to be + * the first bit number in the mask where 0 occurs (with bit number 0 + * representing the highest order bit). + * + * We say a mask is normal if every bit is 0, past the index of the mask. + * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b, + * and m is a normal mask, then the route applies to every descendant of n. + * If the index(m) < rn_b, this implies the trailing last few bits of k + * before bit b are all 0, (and hence consequently true of every descendant + * of n), so the route applies to all descendants of the node as well. + * + * Similar logic shows that a non-normal mask m such that + * index(m) <= index(n) could potentially apply to many children of n. + * Thus, for each non-host route, we attach its mask to a list at an internal + * node as high in the tree as we can go. + * + * The present version of the code makes use of normal routes in short- + * circuiting an explict mask and compare operation when testing whether + * a key satisfies a normal route, and also in remembering the unique leaf + * that governs a subtree. + */ + +struct radix_node * +rn_search(v_arg, head) + void *v_arg; + struct radix_node *head; +{ + struct radix_node *x; + caddr_t v; + + for (x = head, v = v_arg; x->rn_b >= 0;) { + if (x->rn_bmask & v[x->rn_off]) + x = x->rn_r; + else + x = x->rn_l; + } + return (x); +} + +struct radix_node * +rn_search_m(v_arg, head, m_arg) + struct radix_node *head; + void *v_arg, *m_arg; +{ + struct radix_node *x; + caddr_t v = v_arg, m = m_arg; + + for (x = head; x->rn_b >= 0;) { + if ((x->rn_bmask & m[x->rn_off]) && + (x->rn_bmask & v[x->rn_off])) + x = x->rn_r; + else + x = x->rn_l; + } + return x; +} + +int +rn_refines(m_arg, n_arg) + void *m_arg, *n_arg; +{ + caddr_t m = m_arg, n = n_arg; + caddr_t lim, lim2 = lim = n + *(u_char *)n; + int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); + int masks_are_equal = 1; + + if (longer > 0) + lim -= longer; + while (n < lim) { + if (*n & ~(*m)) + return 0; + if (*n++ != *m++) + masks_are_equal = 0; + } + while (n < lim2) + if (*n++) + return 0; + if (masks_are_equal && (longer < 0)) + for (lim2 = m - longer; m < lim2; ) + if (*m++) + return 1; + return (!masks_are_equal); +} + +struct radix_node * +rn_lookup(v_arg, m_arg, head) + void *v_arg, *m_arg; + struct radix_node_head *head; +{ + struct radix_node *x; + caddr_t netmask = 0; + + if (m_arg) { + if ((x = rn_addmask(m_arg, 1, head->rnh_treetop->rn_off)) == 0) + return (0); + netmask = x->rn_key; + } + x = rn_match(v_arg, head); + if (x && netmask) { + while (x && x->rn_mask != netmask) + x = x->rn_dupedkey; + } + return x; +} + +static int +rn_satisfies_leaf(trial, leaf, skip) + char *trial; + struct radix_node *leaf; + int skip; +{ + char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask; + char *cplim; + int length = min(*(u_char *)cp, *(u_char *)cp2); + + if (cp3 == 0) + cp3 = rn_ones; + else + length = min(length, *(u_char *)cp3); + cplim = cp + length; + cp3 += skip; + cp2 += skip; + for (cp += skip; cp < cplim; cp++, cp2++, cp3++) + if ((*cp ^ *cp2) & *cp3) + return 0; + return 1; +} + +struct radix_node * +rn_match(v_arg, head) + void *v_arg; + struct radix_node_head *head; +{ + caddr_t v = v_arg; + struct radix_node *t = head->rnh_treetop, *x; + caddr_t cp = v, cp2; + caddr_t cplim; + struct radix_node *saved_t, *top = t; + int off = t->rn_off, vlen = *(u_char *)cp, matched_off; + int test, b, rn_b; + + /* + * Open code rn_search(v, top) to avoid overhead of extra + * subroutine call. + */ + for (; t->rn_b >= 0; ) { + if (t->rn_bmask & cp[t->rn_off]) + t = t->rn_r; + else + t = t->rn_l; + } + /* + * See if we match exactly as a host destination + * or at least learn how many bits match, for normal mask finesse. + * + * It doesn't hurt us to limit how many bytes to check + * to the length of the mask, since if it matches we had a genuine + * match and the leaf we have is the most specific one anyway; + * if it didn't match with a shorter length it would fail + * with a long one. This wins big for class B&C netmasks which + * are probably the most common case... + */ + if (t->rn_mask) + vlen = *(u_char *)t->rn_mask; + cp += off; + cp2 = t->rn_key + off; + cplim = v + vlen; + for (; cp < cplim; cp++, cp2++) + if (*cp != *cp2) + goto on1; + /* + * This extra grot is in case we are explicitly asked + * to look up the default. Ugh! + */ + if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey) + t = t->rn_dupedkey; + return t; +on1: + test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */ + for (b = 7; (test >>= 1) > 0;) + b--; + matched_off = cp - v; + b += matched_off << 3; + rn_b = -1 - b; + /* + * If there is a host route in a duped-key chain, it will be first. + */ + if ((saved_t = t)->rn_mask == 0) + t = t->rn_dupedkey; + for (; t; t = t->rn_dupedkey) + /* + * Even if we don't match exactly as a host, + * we may match if the leaf we wound up at is + * a route to a net. + */ + if (t->rn_flags & RNF_NORMAL) { + if (rn_b <= t->rn_b) + return t; + } else if (rn_satisfies_leaf(v, t, matched_off)) + return t; + t = saved_t; + /* start searching up the tree */ + do { + struct radix_mask *m; + t = t->rn_p; + m = t->rn_mklist; + if (m) { + /* + * If non-contiguous masks ever become important + * we can restore the masking and open coding of + * the search and satisfaction test and put the + * calculation of "off" back before the "do". + */ + do { + if (m->rm_flags & RNF_NORMAL) { + if (rn_b <= m->rm_b) + return (m->rm_leaf); + } else { + off = min(t->rn_off, matched_off); + x = rn_search_m(v, t, m->rm_mask); + while (x && x->rn_mask != m->rm_mask) + x = x->rn_dupedkey; + if (x && rn_satisfies_leaf(v, x, off)) + return x; + } + m = m->rm_mklist; + } while (m); + } + } while (t != top); + return 0; +} + +#ifdef RN_DEBUG +int rn_nodenum; +struct radix_node *rn_clist; +int rn_saveinfo; +int rn_debug = 1; +#endif + +struct radix_node * +rn_newpair(v, b, nodes) + void *v; + int b; + struct radix_node nodes[2]; +{ + struct radix_node *tt = nodes, *t = tt + 1; + t->rn_b = b; + t->rn_bmask = 0x80 >> (b & 7); + t->rn_l = tt; + t->rn_off = b >> 3; + tt->rn_b = -1; + tt->rn_key = (caddr_t)v; + tt->rn_p = t; + tt->rn_flags = t->rn_flags = RNF_ACTIVE; +#ifdef RN_DEBUG + tt->rn_info = rn_nodenum++; + t->rn_info = rn_nodenum++; + tt->rn_twin = t; + tt->rn_ybro = rn_clist; + rn_clist = tt; +#endif + return t; +} + +struct radix_node * +rn_insert(v_arg, head, dupentry, nodes) + void *v_arg; + struct radix_node_head *head; + int *dupentry; + struct radix_node nodes[2]; +{ + caddr_t v = v_arg; + struct radix_node *top = head->rnh_treetop; + int head_off = top->rn_off, vlen = (int)*((u_char *)v); + struct radix_node *t = rn_search(v_arg, top); + caddr_t cp = v + head_off; + int b; + struct radix_node *tt; + +#ifdef RN_DEBUG + if (rn_debug) + log(LOG_DEBUG, "rn_insert(%p,%p,%p,%p)\n", v_arg, head, dupentry, nodes); +#endif + /* + * Find first bit at which v and t->rn_key differ + */ + { + caddr_t cp2 = t->rn_key + head_off; + int cmp_res; + caddr_t cplim = v + vlen; + + while (cp < cplim) + if (*cp2++ != *cp++) + goto on1; + *dupentry = 1; + return t; +on1: + *dupentry = 0; + cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; + for (b = (cp - v) << 3; cmp_res; b--) + cmp_res >>= 1; + } + { + struct radix_node *p, *x = top; + cp = v; + do { + p = x; + if (cp[x->rn_off] & x->rn_bmask) + x = x->rn_r; + else + x = x->rn_l; + } while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */ +#ifdef RN_DEBUG + if (rn_debug) + log(LOG_DEBUG, "rn_insert: Going In:\n"); // traverse(p); +#endif + t = rn_newpair(v_arg, b, nodes); + tt = t->rn_l; + if ((cp[p->rn_off] & p->rn_bmask) == 0) + p->rn_l = t; + else + p->rn_r = t; + x->rn_p = t; + t->rn_p = p; /* frees x, p as temp vars below */ + if ((cp[t->rn_off] & t->rn_bmask) == 0) { + t->rn_r = x; + } else { + t->rn_r = tt; + t->rn_l = x; + } +#ifdef RN_DEBUG + if (rn_debug) + log(LOG_DEBUG, "rn_insert: Coming Out:\n"); // traverse(p); +#endif + } + return (tt); +} + +struct radix_node * +rn_addmask(n_arg, search, skip) + int search, skip; + void *n_arg; +{ + caddr_t netmask = (caddr_t)n_arg; + struct radix_node *x; + caddr_t cp, cplim; + int b = 0, mlen, j; + int maskduplicated, m0, isnormal; + struct radix_node *saved_x; + static int last_zeroed = 0; + +#ifdef RN_DEBUG + if (rn_debug) + log(LOG_DEBUG, "rn_addmask(%p,%d,%d)\n", n_arg, search, skip); +#endif + mlen = *(u_char *)netmask; + if ((mlen = *(u_char *)netmask) > max_keylen) + mlen = max_keylen; + if (skip == 0) + skip = 1; + if (mlen <= skip) + return (mask_rnhead->rnh_nodes); + if (skip > 1) + Bcopy(rn_ones + 1, addmask_key + 1, skip - 1); + if ((m0 = mlen) > skip) + Bcopy(netmask + skip, addmask_key + skip, mlen - skip); + /* + * Trim trailing zeroes. + */ + for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;) + cp--; + mlen = cp - addmask_key; + if (mlen <= skip) { + if (m0 >= last_zeroed) + last_zeroed = mlen; + return (mask_rnhead->rnh_nodes); + } + if (m0 < last_zeroed) + Bzero(addmask_key + m0, last_zeroed - m0); + *addmask_key = last_zeroed = mlen; + x = rn_search(addmask_key, rn_masktop); + if (Bcmp(addmask_key, x->rn_key, mlen) != 0) + x = 0; + if (x || search) + return (x); + R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x)); + if ((saved_x = x) == 0) + return (0); + Bzero(x, max_keylen + 2 * sizeof (*x)); + netmask = cp = (caddr_t)(x + 2); + Bcopy(addmask_key, cp, mlen); + x = rn_insert(cp, mask_rnhead, &maskduplicated, x); + if (maskduplicated) { +#if 0 + log(LOG_ERR, "rn_addmask: mask impossibly already in tree\n"); +#endif + Free(saved_x); + return (x); + } + /* + * Calculate index of mask, and check for normalcy. + */ + cplim = netmask + mlen; + isnormal = 1; + for (cp = netmask + skip; (cp < cplim) && *(u_char *)cp == 0xff;) + cp++; + if (cp != cplim) { + for (j = 0x80; (j & *cp) != 0; j >>= 1) + b++; + if (*cp != normal_chars[b] || cp != (cplim - 1)) + isnormal = 0; + } + b += (cp - netmask) << 3; + x->rn_b = -1 - b; + if (isnormal) + x->rn_flags |= RNF_NORMAL; + return (x); +} + +static int /* XXX: arbitrary ordering for non-contiguous masks */ +rn_lexobetter(m_arg, n_arg) + void *m_arg, *n_arg; +{ + u_char *mp = m_arg, *np = n_arg, *lim; + + if (*mp > *np) + return 1; /* not really, but need to check longer one first */ + if (*mp == *np) + for (lim = mp + *mp; mp < lim;) + if (*mp++ > *np++) + return 1; + return 0; +} + +static struct radix_mask * +rn_new_radix_mask(tt, next) + struct radix_node *tt; + struct radix_mask *next; +{ + struct radix_mask *m; + + MKGet(m); + if (m == 0) { +#if 0 + log(LOG_ERR, "Mask for route not entered\n"); +#endif + return (0); + } + Bzero(m, sizeof *m); + m->rm_b = tt->rn_b; + m->rm_flags = tt->rn_flags; + if (tt->rn_flags & RNF_NORMAL) + m->rm_leaf = tt; + else + m->rm_mask = tt->rn_mask; + m->rm_mklist = next; + tt->rn_mklist = m; + return m; +} + +struct radix_node * +rn_addroute(v_arg, n_arg, head, treenodes) + void *v_arg, *n_arg; + struct radix_node_head *head; + struct radix_node treenodes[2]; +{ + caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; + struct radix_node *t, *x = NULL, *tt; + struct radix_node *saved_tt, *top = head->rnh_treetop; + short b = 0, b_leaf = 0; + int keyduplicated; + caddr_t mmask; + struct radix_mask *m, **mp; + +#ifdef RN_DEBUG + if (rn_debug) + log(LOG_DEBUG, "rn_addroute(%p,%p,%p,%p)\n", v_arg, n_arg, head, treenodes); +#endif + /* + * In dealing with non-contiguous masks, there may be + * many different routes which have the same mask. + * We will find it useful to have a unique pointer to + * the mask to speed avoiding duplicate references at + * nodes and possibly save time in calculating indices. + */ + if (netmask) { + if ((x = rn_addmask(netmask, 0, top->rn_off)) == 0) + return (0); + b_leaf = x->rn_b; + b = -1 - x->rn_b; + netmask = x->rn_key; + } + /* + * Deal with duplicated keys: attach node to previous instance + */ + saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes); + if (keyduplicated) { + for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) { + if (tt->rn_mask == netmask) + return (0); + if (netmask == 0 || + (tt->rn_mask && + ((b_leaf < tt->rn_b) || /* index(netmask) > node */ + rn_refines(netmask, tt->rn_mask) || + rn_lexobetter(netmask, tt->rn_mask)))) + break; + } + /* + * If the mask is not duplicated, we wouldn't + * find it among possible duplicate key entries + * anyway, so the above test doesn't hurt. + * + * We sort the masks for a duplicated key the same way as + * in a masklist -- most specific to least specific. + * This may require the unfortunate nuisance of relocating + * the head of the list. + * + * We also reverse, or doubly link the list through the + * parent pointer. + */ + if (tt == saved_tt) { + struct radix_node *xx = x; + /* link in at head of list */ + (tt = treenodes)->rn_dupedkey = t; + tt->rn_flags = t->rn_flags; + tt->rn_p = x = t->rn_p; + t->rn_p = tt; + if (x->rn_l == t) + x->rn_l = tt; + else + x->rn_r = tt; + saved_tt = tt; + x = xx; + } else { + (tt = treenodes)->rn_dupedkey = t->rn_dupedkey; + t->rn_dupedkey = tt; + tt->rn_p = t; + if (tt->rn_dupedkey) + tt->rn_dupedkey->rn_p = tt; + } +#ifdef RN_DEBUG + t=tt+1; + tt->rn_info = rn_nodenum++; + t->rn_info = rn_nodenum++; + tt->rn_twin = t; + tt->rn_ybro = rn_clist; + rn_clist = tt; +#endif + tt->rn_key = (caddr_t) v; + tt->rn_b = -1; + tt->rn_flags = RNF_ACTIVE; + } + /* + * Put mask in tree. + */ + if (netmask) { + tt->rn_mask = netmask; + tt->rn_b = x->rn_b; + tt->rn_flags |= x->rn_flags & RNF_NORMAL; + } + t = saved_tt->rn_p; + if (keyduplicated) + goto on2; + b_leaf = -1 - t->rn_b; + if (t->rn_r == saved_tt) + x = t->rn_l; + else + x = t->rn_r; + /* Promote general routes from below */ + if (x->rn_b < 0) { + for (mp = &t->rn_mklist; x; x = x->rn_dupedkey) + if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) { + *mp = m = rn_new_radix_mask(x, 0); + if (m) + mp = &m->rm_mklist; + } + } else if (x->rn_mklist) { + /* + * Skip over masks whose index is > that of new node + */ + for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) + if (m->rm_b >= b_leaf) + break; + t->rn_mklist = m; + *mp = 0; + } +on2: + /* Add new route to highest possible ancestor's list */ + if ((netmask == 0) || (b > t->rn_b )) + return tt; /* can't lift at all */ + b_leaf = tt->rn_b; + do { + x = t; + t = t->rn_p; + } while (b <= t->rn_b && x != top); + /* + * Search through routes associated with node to + * insert new route according to index. + * Need same criteria as when sorting dupedkeys to avoid + * double loop on deletion. + */ + for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) { + if (m->rm_b < b_leaf) + continue; + if (m->rm_b > b_leaf) + break; + if (m->rm_flags & RNF_NORMAL) { + mmask = m->rm_leaf->rn_mask; + if (tt->rn_flags & RNF_NORMAL) { +#if 0 + log(LOG_ERR, "Non-unique normal route," + " mask not entered\n"); +#endif + return tt; + } + } else + mmask = m->rm_mask; + if (mmask == netmask) { + m->rm_refs++; + tt->rn_mklist = m; + return tt; + } + if (rn_refines(netmask, mmask) + || rn_lexobetter(netmask, mmask)) + break; + } + *mp = rn_new_radix_mask(tt, *mp); + return tt; +} + +struct radix_node * +rn_delete(v_arg, netmask_arg, head) + void *v_arg, *netmask_arg; + struct radix_node_head *head; +{ + struct radix_node *t, *p, *x, *tt; + struct radix_mask *m, *saved_m, **mp; + struct radix_node *dupedkey, *saved_tt, *top; + caddr_t v, netmask; + int b, head_off, vlen; + + v = v_arg; + netmask = netmask_arg; + x = head->rnh_treetop; + tt = rn_search(v, x); + head_off = x->rn_off; + vlen = *(u_char *)v; + saved_tt = tt; + top = x; + if (tt == 0 || + Bcmp(v + head_off, tt->rn_key + head_off, vlen - head_off)) + return (0); + /* + * Delete our route from mask lists. + */ + if (netmask) { + if ((x = rn_addmask(netmask, 1, head_off)) == 0) + return (0); + netmask = x->rn_key; + while (tt->rn_mask != netmask) + if ((tt = tt->rn_dupedkey) == 0) + return (0); + } + if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0) + goto on1; + if (tt->rn_flags & RNF_NORMAL) { + if (m->rm_leaf != tt || m->rm_refs > 0) { +#if 0 + log(LOG_ERR, "rn_delete: inconsistent annotation\n"); +#endif + return 0; /* dangling ref could cause disaster */ + } + } else { + if (m->rm_mask != tt->rn_mask) { +#if 0 + log(LOG_ERR, "rn_delete: inconsistent annotation\n"); +#endif + goto on1; + } + if (--m->rm_refs >= 0) + goto on1; + } + b = -1 - tt->rn_b; + t = saved_tt->rn_p; + if (b > t->rn_b) + goto on1; /* Wasn't lifted at all */ + do { + x = t; + t = t->rn_p; + } while (b <= t->rn_b && x != top); + for (mp = &x->rn_mklist; (m = *mp) != NULL; mp = &m->rm_mklist) + if (m == saved_m) { + *mp = m->rm_mklist; + MKFree(m); + break; + } + if (m == 0) { +#if 0 + log(LOG_ERR, "rn_delete: couldn't find our annotation\n"); +#endif + if (tt->rn_flags & RNF_NORMAL) + return (0); /* Dangling ref to us */ + } +on1: + /* + * Eliminate us from tree + */ + if (tt->rn_flags & RNF_ROOT) + return (0); +#ifdef RN_DEBUG + /* Get us out of the creation list */ + for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) + ; + if (t) t->rn_ybro = tt->rn_ybro; +#endif + t = tt->rn_p; + dupedkey = saved_tt->rn_dupedkey; + if (dupedkey) { + /* + * Here, tt is the deletion target and + * saved_tt is the head of the dupedkey chain. + */ + if (tt == saved_tt) { + x = dupedkey; + x->rn_p = t; + if (t->rn_l == tt) + t->rn_l = x; + else + t->rn_r = x; + } else { + /* find node in front of tt on the chain */ + for (x = p = saved_tt; p && p->rn_dupedkey != tt;) + p = p->rn_dupedkey; + if (p) { + p->rn_dupedkey = tt->rn_dupedkey; + if (tt->rn_dupedkey) + tt->rn_dupedkey->rn_p = p; + } +#if 0 + else + log(LOG_ERR, "rn_delete: couldn't find us\n"); +#endif + } + t = tt + 1; + if (t->rn_flags & RNF_ACTIVE) { +#ifndef RN_DEBUG + *++x = *t; + p = t->rn_p; +#else + b = t->rn_info; + *++x = *t; + t->rn_info = b; + p = t->rn_p; +#endif + if (p->rn_l == t) + p->rn_l = x; + else + p->rn_r = x; + x->rn_l->rn_p = x; + x->rn_r->rn_p = x; + } + goto out; + } + if (t->rn_l == tt) + x = t->rn_r; + else + x = t->rn_l; + p = t->rn_p; + if (p->rn_r == t) + p->rn_r = x; + else + p->rn_l = x; + x->rn_p = p; + /* + * Demote routes attached to us. + */ + if (t->rn_mklist) { + if (x->rn_b >= 0) { + for (mp = &x->rn_mklist; (m = *mp) != NULL;) + mp = &m->rm_mklist; + *mp = t->rn_mklist; + } else { + /* If there are any key,mask pairs in a sibling + duped-key chain, some subset will appear sorted + in the same order attached to our mklist */ + for (m = t->rn_mklist; m && x; x = x->rn_dupedkey) + if (m == x->rn_mklist) { + struct radix_mask *mm = m->rm_mklist; + x->rn_mklist = 0; + if (--(m->rm_refs) < 0) + MKFree(m); + m = mm; + } +#if 0 + if (m) + log(LOG_ERR, "%s %p at %p\n", + "rn_delete: Orphaned Mask", m, x); +#endif + } + } + /* + * We may be holding an active internal node in the tree. + */ + x = tt + 1; + if (t != x) { +#ifndef RN_DEBUG + *t = *x; +#else + b = t->rn_info; + *t = *x; + t->rn_info = b; +#endif + t->rn_l->rn_p = t; + t->rn_r->rn_p = t; + p = x->rn_p; + if (p->rn_l == x) + p->rn_l = t; + else + p->rn_r = t; + } +out: + tt->rn_flags &= ~RNF_ACTIVE; + tt[1].rn_flags &= ~RNF_ACTIVE; + return (tt); +} + +int +rn_walktree(h, f, w) + struct radix_node_head *h; + int (*f) __P((struct radix_node *, void *)); + void *w; +{ + int error; + struct radix_node *base, *next; + struct radix_node *rn = h->rnh_treetop; + /* + * This gets complicated because we may delete the node + * while applying the function f to it, so we need to calculate + * the successor node in advance. + */ + /* First time through node, go left */ + while (rn->rn_b >= 0) + rn = rn->rn_l; + for (;;) { + base = rn; + /* If at right child go back up, otherwise, go right */ + while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0) + rn = rn->rn_p; + /* Find the next *leaf* since next node might vanish, too */ + for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;) + rn = rn->rn_l; + next = rn; + /* Process leaves */ + while ((rn = base) != NULL) { + base = rn->rn_dupedkey; + if (!(rn->rn_flags & RNF_ROOT) + && (error = (*f)(rn, w))) + return (error); + } + rn = next; + if (rn->rn_flags & RNF_ROOT) + return (0); + } + /* NOTREACHED */ +} + +int +rn_inithead(head, off) + void **head; + int off; +{ + struct radix_node_head *rnh; + + if (*head) + return (1); + R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh)); + if (rnh == 0) + return (0); + *head = rnh; + return rn_inithead0(rnh, off); +} + +int +rn_inithead0(rnh, off) + struct radix_node_head *rnh; + int off; +{ + struct radix_node *t, *tt, *ttt; + + Bzero(rnh, sizeof (*rnh)); + t = rn_newpair(rn_zeros, off, rnh->rnh_nodes); + ttt = rnh->rnh_nodes + 2; + t->rn_r = ttt; + t->rn_p = t; + tt = t->rn_l; + tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE; + tt->rn_b = -1 - off; + *ttt = *tt; + ttt->rn_key = rn_ones; + rnh->rnh_addaddr = rn_addroute; + rnh->rnh_deladdr = rn_delete; + rnh->rnh_matchaddr = rn_match; + rnh->rnh_lookup = rn_lookup; + rnh->rnh_walktree = rn_walktree; + rnh->rnh_treetop = t; + return (1); +} + +void +rn_init() +{ + char *cp, *cplim; + + if (max_keylen == 0) { +#if 0 + log(LOG_ERR, + "rn_init: radix functions require max_keylen be set\n"); +#endif + return; + } + if (rn_zeros == NULL) { + R_Malloc(rn_zeros, char *, 3 * max_keylen); + } + if (rn_zeros == NULL) + panic("rn_init"); + Bzero(rn_zeros, 3 * max_keylen); + rn_ones = cp = rn_zeros + max_keylen; + addmask_key = cplim = rn_ones + max_keylen; + while (cp < cplim) + *cp++ = -1; + if (rn_inithead((void *)&mask_rnhead, 0) == 0) + panic("rn_init 2"); +} + + +static int +rn_freenode(struct radix_node *n, void *p) +{ + struct radix_node_head *rnh = p; + struct radix_node *d; + + d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); + if (d != NULL) { + FreeS(d, max_keylen + 2 * sizeof (*d)); + } + return 0; +} + + +void +rn_freehead(rnh) + struct radix_node_head *rnh; +{ + + (void)rn_walktree(rnh, rn_freenode, rnh); + + rnh->rnh_addaddr = NULL; + rnh->rnh_deladdr = NULL; + rnh->rnh_matchaddr = NULL; + rnh->rnh_lookup = NULL; + rnh->rnh_walktree = NULL; + + Free(rnh); +} + + +void +rn_fini() +{ + struct radix_mask *m; + + if (rn_zeros != NULL) { + FreeS(rn_zeros, 3 * max_keylen); + rn_zeros = NULL; + } + + if (mask_rnhead != NULL) { + rn_freehead(mask_rnhead); + mask_rnhead = NULL; + } + + while ((m = rn_mkfreelist) != NULL) { + rn_mkfreelist = m->rm_mklist; + KFREE(m); + } +} + + +#ifdef USE_MAIN + +typedef struct myst { + addrfamily_t dst; + addrfamily_t mask; + struct radix_node nodes[2]; +} myst_t; + +int +main(int argc, char *argv[]) +{ + struct radix_node_head *rnh; + struct radix_node *rn; + addrfamily_t af, mf; + myst_t st1, st2, *stp; + + memset(&st1, 0, sizeof(st1)); + memset(&st2, 0, sizeof(st2)); + memset(&af, 0, sizeof(af)); + + rn_init(); + + rnh = NULL; + rn_inithead(&rnh, offsetof(addrfamily_t, adf_addr) << 3); + + st1.dst.adf_len = sizeof(st1); + st1.mask.adf_len = sizeof(st1); + st1.dst.adf_addr.in4.s_addr = inet_addr("127.0.0.0"); + st1.mask.adf_addr.in4.s_addr = inet_addr("255.0.0.0"); + rn = rnh->rnh_addaddr(&st1.dst, &st1.mask, rnh, st1.nodes); + printf("add.1 %p\n", rn); + + st2.dst.adf_len = sizeof(st2); + st2.mask.adf_len = sizeof(st2); + st2.dst.adf_addr.in4.s_addr = inet_addr("127.0.1.0"); + st2.mask.adf_addr.in4.s_addr = inet_addr("255.255.255.0"); + rn = rnh->rnh_addaddr(&st2.dst, &st2.mask, rnh, st2.nodes); + printf("add.2 %p\n", rn); + + af.adf_len = sizeof(af); + af.adf_addr.in4.s_addr = inet_addr("127.0.1.0"); + rn = rnh->rnh_matchaddr(&af, rnh); + if (rn != NULL) { + printf("1.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask); + stp = rn->rn_key; + printf("%s/", inet_ntoa(stp->dst.adf_addr.in4)); + stp = rn->rn_mask; + printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4)); + } + + mf.adf_len = sizeof(mf); + mf.adf_addr.in4.s_addr = inet_addr("255.255.255.0"); + rn = rnh->rnh_lookup(&af, &mf, rnh); + if (rn != NULL) { + printf("2.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask); + stp = rn->rn_key; + printf("%s/", inet_ntoa(stp->dst.adf_addr.in4)); + stp = rn->rn_mask; + printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4)); + } + + af.adf_len = sizeof(af); + af.adf_addr.in4.s_addr = inet_addr("126.0.0.1"); + rn = rnh->rnh_matchaddr(&af, rnh); + if (rn != NULL) { + printf("3.lookup = %p key %p mask %p\n", rn, rn->rn_key, rn->rn_mask); + stp = rn->rn_key; + printf("%s/", inet_ntoa(stp->dst.adf_addr.in4)); + stp = rn->rn_mask; + printf("%s\n", inet_ntoa(stp->dst.adf_addr.in4)); + } + + return 0; +} + + +void +log(int level, char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} +#endif + + +#ifndef _KERNEL +void +panic(char *str) +{ + fputs(str, stderr); + abort(); +} +#endif diff --git a/contrib/ipfilter/radix_ipf.h b/contrib/ipfilter/radix_ipf.h new file mode 100644 index 000000000000..1dada6034def --- /dev/null +++ b/contrib/ipfilter/radix_ipf.h @@ -0,0 +1,208 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1988, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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. + * + * @(#)radix.h 8.2 (Berkeley) 10/31/94 + */ + +#ifndef _NET_RADIX_H_ +#define _NET_RADIX_H_ +#ifndef _RADIX_H_ +#define _RADIX_H_ +#endif /* _RADIX_H_ */ + +#ifndef __P +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +#ifdef __sgi +# define radix_mask ipf_radix_mask +# define radix_node ipf_radix_node +# define radix_node_head ipf_radix_node_head +#endif + +/* + * Radix search tree node layout. + */ + +struct radix_node { + struct radix_mask *rn_mklist; /* list of masks contained in subtree */ + struct radix_node *rn_p; /* parent */ + short rn_b; /* bit offset; -1-index(netmask) */ + char rn_bmask; /* node: mask for bit test*/ + u_char rn_flags; /* enumerated next */ +#define RNF_NORMAL 1 /* leaf contains normal route */ +#define RNF_ROOT 2 /* leaf is root leaf for tree */ +#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */ + union { + struct { /* leaf only data: */ + caddr_t rn_Key; /* object of search */ + caddr_t rn_Mask; /* netmask, if present */ + struct radix_node *rn_Dupedkey; + } rn_leaf; + struct { /* node only data: */ + int rn_Off; /* where to start compare */ + struct radix_node *rn_L;/* progeny */ + struct radix_node *rn_R;/* progeny */ + } rn_node; + } rn_u; +#ifdef RN_DEBUG + int rn_info; + struct radix_node *rn_twin; + struct radix_node *rn_ybro; +#endif +}; + +#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey +#define rn_key rn_u.rn_leaf.rn_Key +#define rn_mask rn_u.rn_leaf.rn_Mask +#define rn_off rn_u.rn_node.rn_Off +#define rn_l rn_u.rn_node.rn_L +#define rn_r rn_u.rn_node.rn_R + +/* + * Annotations to tree concerning potential routes applying to subtrees. + */ + +struct radix_mask { + short rm_b; /* bit offset; -1-index(netmask) */ + char rm_unused; /* cf. rn_bmask */ + u_char rm_flags; /* cf. rn_flags */ + struct radix_mask *rm_mklist; /* more masks to try */ + union { + caddr_t rmu_mask; /* the mask */ + struct radix_node *rmu_leaf; /* for normal routes */ + } rm_rmu; + int rm_refs; /* # of references to this struct */ +}; + +#define rm_mask rm_rmu.rmu_mask +#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ + +#define MKGet(m) {\ + if (rn_mkfreelist) {\ + m = rn_mkfreelist; \ + rn_mkfreelist = (m)->rm_mklist; \ + } else \ + R_Malloc(m, struct radix_mask *, sizeof (*(m))); }\ + +#define MKFree(m) { (m)->rm_mklist = rn_mkfreelist; rn_mkfreelist = (m);} + +struct radix_node_head { + struct radix_node *rnh_treetop; + struct radix_node *rnh_leaflist; + u_long rnh_hits; + u_int rnh_number; + u_int rnh_ref; + int rnh_addrsize; /* permit, but not require fixed keys */ + int rnh_pktsize; /* permit, but not require fixed keys */ + struct radix_node *(*rnh_addaddr) /* add based on sockaddr */ + __P((void *v, void *mask, + struct radix_node_head *head, struct radix_node nodes[])); + struct radix_node *(*rnh_addpkt) /* add based on packet hdr */ + __P((void *v, void *mask, + struct radix_node_head *head, struct radix_node nodes[])); + struct radix_node *(*rnh_deladdr) /* remove based on sockaddr */ + __P((void *v, void *mask, struct radix_node_head *head)); + struct radix_node *(*rnh_delpkt) /* remove based on packet hdr */ + __P((void *v, void *mask, struct radix_node_head *head)); + struct radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ + __P((void *v, struct radix_node_head *head)); + struct radix_node *(*rnh_lookup) /* locate based on sockaddr */ + __P((void *v, void *mask, struct radix_node_head *head)); + struct radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ + __P((void *v, struct radix_node_head *head)); + int (*rnh_walktree) /* traverse tree */ + __P((struct radix_node_head *, + int (*)(struct radix_node *, void *), void *)); + struct radix_node rnh_nodes[3]; /* empty tree for common case */ +}; + + +#define Bcmp(a, b, n) bcmp(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n)) +#if defined(linux) && defined(_KERNEL) +# define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) +#else +# define Bcopy(a, b, n) bcopy(((caddr_t)(a)), ((caddr_t)(b)), (unsigned)(n)) +#endif +#define Bzero(p, n) bzero((caddr_t)(p), (unsigned)(n)); +#define R_Malloc(p, t, n) KMALLOCS(p, t, n) +#define FreeS(p, z) KFREES(p, z) +#define Free(p) KFREE(p) + +#if (defined(__osf__) || (IRIX >= 60516)) && defined(_KERNEL) +# define rn_init ipf_rn_init +# define rn_fini ipf_rn_fini +# define rn_inithead ipf_rn_inithead +# define rn_freehead ipf_rn_freehead +# define rn_inithead0 ipf_rn_inithead0 +# define rn_refines ipf_rn_refines +# define rn_walktree ipf_rn_walktree +# define rn_addmask ipf_rn_addmask +# define rn_addroute ipf_rn_addroute +# define rn_delete ipf_rn_delete +# define rn_insert ipf_rn_insert +# define rn_lookup ipf_rn_lookup +# define rn_match ipf_rn_match +# define rn_newpair ipf_rn_newpair +# define rn_search ipf_rn_search +# define rn_search_m ipf_rn_search_m +# define max_keylen ipf_maxkeylen +# define rn_mkfreelist ipf_rn_mkfreelist +# define rn_zeros ipf_rn_zeros +# define rn_ones ipf_rn_ones +# define rn_satisfies_leaf ipf_rn_satisfies_leaf +# define rn_lexobetter ipf_rn_lexobetter +# define rn_new_radix_mask ipf_rn_new_radix_mask +# define rn_freenode ipf_rn_freenode +#endif + +void rn_init __P((void)); +void rn_fini __P((void)); +int rn_inithead __P((void **, int)); +void rn_freehead __P((struct radix_node_head *)); +int rn_inithead0 __P((struct radix_node_head *, int)); +int rn_refines __P((void *, void *)); +int rn_walktree __P((struct radix_node_head *, + int (*)(struct radix_node *, void *), void *)); +struct radix_node + *rn_addmask __P((void *, int, int)), + *rn_addroute __P((void *, void *, struct radix_node_head *, + struct radix_node [2])), + *rn_delete __P((void *, void *, struct radix_node_head *)), + *rn_insert __P((void *, struct radix_node_head *, int *, + struct radix_node [2])), + *rn_lookup __P((void *, void *, struct radix_node_head *)), + *rn_match __P((void *, struct radix_node_head *)), + *rn_newpair __P((void *, int, struct radix_node[2])), + *rn_search __P((void *, struct radix_node *)), + *rn_search_m __P((void *, struct radix_node *, void *)); + +#endif /* _NET_RADIX_H_ */ diff --git a/contrib/ipfilter/rules/.cvsignore b/contrib/ipfilter/rules/.cvsignore new file mode 100644 index 000000000000..3e757656cf36 --- /dev/null +++ b/contrib/ipfilter/rules/.cvsignore @@ -0,0 +1 @@ +new diff --git a/contrib/ipfilter/rules/example.1 b/contrib/ipfilter/rules/example.1 index ff93f492cafe..3da9f3ccab5c 100644 --- a/contrib/ipfilter/rules/example.1 +++ b/contrib/ipfilter/rules/example.1 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # block all incoming TCP packets on le0 from host 10.1.1.1 to any destination. # diff --git a/contrib/ipfilter/rules/example.10 b/contrib/ipfilter/rules/example.10 index 560d1e670f61..f7a0b011e144 100644 --- a/contrib/ipfilter/rules/example.10 +++ b/contrib/ipfilter/rules/example.10 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # pass ack packets (ie established connection) # diff --git a/contrib/ipfilter/rules/example.11 b/contrib/ipfilter/rules/example.11 index c6b4e7ff0d73..1cefa9a3b35d 100644 --- a/contrib/ipfilter/rules/example.11 +++ b/contrib/ipfilter/rules/example.11 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # allow any TCP packets from the same subnet as foo is on through to host # 10.1.1.2 if they are destined for port 6667. diff --git a/contrib/ipfilter/rules/example.12 b/contrib/ipfilter/rules/example.12 index c0ba1d3cdda1..6dbaef58c561 100644 --- a/contrib/ipfilter/rules/example.12 +++ b/contrib/ipfilter/rules/example.12 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # get rid of all short IP fragments (too small for valid comparison) # diff --git a/contrib/ipfilter/rules/example.13 b/contrib/ipfilter/rules/example.13 index 854f07f1694f..ca741148931e 100644 --- a/contrib/ipfilter/rules/example.13 +++ b/contrib/ipfilter/rules/example.13 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # Log all short TCP packets to qe3, with 10.3.3.3 as the intended # destination for the packet. diff --git a/contrib/ipfilter/rules/example.2 b/contrib/ipfilter/rules/example.2 index 4f81725eeb0c..81e7d25c7c71 100644 --- a/contrib/ipfilter/rules/example.2 +++ b/contrib/ipfilter/rules/example.2 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # block all outgoing TCP packets on le0 from any host to port 23 of # host 10.1.1.2 diff --git a/contrib/ipfilter/rules/example.3 b/contrib/ipfilter/rules/example.3 index cd31f73e7c2b..c5b4344f91ce 100644 --- a/contrib/ipfilter/rules/example.3 +++ b/contrib/ipfilter/rules/example.3 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # block all inbound packets. # diff --git a/contrib/ipfilter/rules/example.4 b/contrib/ipfilter/rules/example.4 index 7918ec2fbd99..f18dcdd0cd27 100644 --- a/contrib/ipfilter/rules/example.4 +++ b/contrib/ipfilter/rules/example.4 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # block all ICMP packets. # diff --git a/contrib/ipfilter/rules/example.5 b/contrib/ipfilter/rules/example.5 index 6d688b5eab80..959dfb836371 100644 --- a/contrib/ipfilter/rules/example.5 +++ b/contrib/ipfilter/rules/example.5 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # test ruleset # diff --git a/contrib/ipfilter/rules/example.6 b/contrib/ipfilter/rules/example.6 index d40f0f3d2a18..e9ce23ac27e6 100644 --- a/contrib/ipfilter/rules/example.6 +++ b/contrib/ipfilter/rules/example.6 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # block all TCP packets with only the SYN flag set (this is the first # packet sent to establish a connection) out of the SYN-ACK pair. diff --git a/contrib/ipfilter/rules/example.7 b/contrib/ipfilter/rules/example.7 index 062de9811935..0ddd7f77628b 100644 --- a/contrib/ipfilter/rules/example.7 +++ b/contrib/ipfilter/rules/example.7 @@ -1,3 +1,4 @@ +# $FreeBSD$ # block all ICMP packets. # block in proto icmp all diff --git a/contrib/ipfilter/rules/example.8 b/contrib/ipfilter/rules/example.8 index baa02581256e..2276b525b17d 100644 --- a/contrib/ipfilter/rules/example.8 +++ b/contrib/ipfilter/rules/example.8 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # block all incoming TCP connections but send back a TCP-RST for ones to # the ident port diff --git a/contrib/ipfilter/rules/example.9 b/contrib/ipfilter/rules/example.9 index daff2031db8e..50bb46a672d8 100644 --- a/contrib/ipfilter/rules/example.9 +++ b/contrib/ipfilter/rules/example.9 @@ -1,3 +1,4 @@ +# $FreeBSD$ # # drop all packets without IP security options # diff --git a/contrib/ipfilter/rules/example.sr b/contrib/ipfilter/rules/example.sr index c4c1994030ba..46fb6f14aaf6 100644 --- a/contrib/ipfilter/rules/example.sr +++ b/contrib/ipfilter/rules/example.sr @@ -1,3 +1,4 @@ +# $FreeBSD$ # # log all inbound packet on le0 which has IP options present # diff --git a/contrib/ipfilter/rules/ip_rules b/contrib/ipfilter/rules/ip_rules new file mode 100644 index 000000000000..9850f16b9306 --- /dev/null +++ b/contrib/ipfilter/rules/ip_rules @@ -0,0 +1,3 @@ +# Used to generate ../ip_rules.c and ../ip_rules.h +pass in all +pass out all diff --git a/contrib/ipfilter/rules/ipmon.conf b/contrib/ipfilter/rules/ipmon.conf new file mode 100644 index 000000000000..47b01463575c --- /dev/null +++ b/contrib/ipfilter/rules/ipmon.conf @@ -0,0 +1,24 @@ +# +# +# +# +match { logtag = 10000 } + do { execute "/usr/bin/mail -s 'logtag 10000' root" }; +match { logtag = 2000, every 10 seconds } + do { execute "echo 'XXXXXXXX tag 2000 packet XXXXXXXX'" }; +# +match { protocol = udp, result = block } + do { execute "/usr/bin/mail -s 'blocked udp' root" +}; +# +match { + srcip = 10.1.0.0/16, dstip = 192.168.1.0/24 } + do { execute "/usr/bin/mail -s 'from 10.1 to 192.168.1' root" +}; +# +match { + rule = 12, logtag = 101, direction = in, result = block, + protocol = udp, srcip = 10.1.0.0/16, dstip = 192.168.1.0/24 } + do { execute "run shell command" +}; +# diff --git a/contrib/ipfilter/rules/pool.conf b/contrib/ipfilter/rules/pool.conf new file mode 100644 index 000000000000..285398ddf3b1 --- /dev/null +++ b/contrib/ipfilter/rules/pool.conf @@ -0,0 +1,4 @@ +# +pool 0 = { !10.0.0.0 - 10.255.255.255, 10.1.0.0 - 10.1.255.255, + 10.1.1.0 - 10.1.1.255, !10.1.2.0 - 10.2.2.255, + 10.1.2.3 - 10.1.2.3, 10.1.2.15 - 10.1.2.15 }; diff --git a/contrib/ipfilter/samples/.cvsignore b/contrib/ipfilter/samples/.cvsignore new file mode 100644 index 000000000000..4d38251c2f4f --- /dev/null +++ b/contrib/ipfilter/samples/.cvsignore @@ -0,0 +1,4 @@ +userauth +proxy +relay +trans_relay diff --git a/contrib/ipfilter/samples/Makefile b/contrib/ipfilter/samples/Makefile index 1dad07900c86..47ab4a26d5c0 100644 --- a/contrib/ipfilter/samples/Makefile +++ b/contrib/ipfilter/samples/Makefile @@ -11,14 +11,14 @@ all: @echo "make sunos5" sunos5: - $(CC) -DSOLARIS2=`uname -r | sh -c 'IFS=. read j n x; echo $$n'` \ - -I.. userauth.c -o userauth -lsocket -lnsl - $(CC) -DSOLARIS2=`uname -r | sh -c 'IFS=. read j n x; echo $$n'` \ - -I.. proxy.c -o proxy -lsocket -lnsl + $(CC) -I.. userauth.c -o userauth -lsocket -lnsl + $(CC) -I.. proxy.c -o proxy -lsocket -lnsl + $(CC) -I.. relay.c -o relay -lsocket -lnsl freebsd freebsd22 netbsd bsd bsdi sunos4 openbsd: $(CC) -I.. userauth.c -o userauth $(CC) -I.. proxy.c -o proxy + $(CC) -I.. relay.c -o relay clean: - /bin/rm -f userauth proxy + /bin/rm -f userauth proxy relay diff --git a/contrib/ipfilter/samples/ipfilter-pb.gif b/contrib/ipfilter/samples/ipfilter-pb.gif index afaefa866541..f729ab1365da 100644 Binary files a/contrib/ipfilter/samples/ipfilter-pb.gif and b/contrib/ipfilter/samples/ipfilter-pb.gif differ diff --git a/contrib/ipfilter/samples/proxy.c b/contrib/ipfilter/samples/proxy.c index ef9a69c356e8..ccf2ac65e646 100644 --- a/contrib/ipfilter/samples/proxy.c +++ b/contrib/ipfilter/samples/proxy.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Sample transparent proxy program. * @@ -45,6 +47,7 @@ #include "netinet/ip_state.h" #include "netinet/ip_proxy.h" #include "netinet/ip_nat.h" +#include "netinet/ipl.h" main(argc, argv) @@ -52,6 +55,7 @@ int argc; char *argv[]; { struct sockaddr_in sin, sloc, sout; + ipfobj_t obj; natlookup_t natlook; natlookup_t *natlookp = &natlook; char buffer[512]; @@ -77,21 +81,27 @@ char *argv[]; exit(-1); } + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(natlook); + obj.ipfo_ptr = &natlook; + obj.ipfo_type = IPFOBJ_NATLOOKUP; + /* * Build up the NAT natlookup structure. */ bzero((char *)&natlook, sizeof(natlook)); natlook.nl_outip = sin.sin_addr; natlook.nl_inip = sloc.sin_addr; - natlook.nl_flags = IPN_TCPUDP; + natlook.nl_flags = IPN_TCP; natlook.nl_outport = ntohs(sin.sin_port); natlook.nl_inport = ntohs(sloc.sin_port); /* * Open the NAT device and lookup the mapping pair. */ - fd = open(IPL_NAT, O_RDONLY); - if (ioctl(fd, SIOCGNATL, &natlookp) == -1) { + fd = open(IPNAT_NAME, O_RDONLY); + if (ioctl(fd, SIOCGNATL, &obj) == -1) { perror("ioctl(SIOCGNATL)"); exit(-1); } @@ -131,6 +141,7 @@ char *extif; struct sockaddr_in usin; u_32_t sum1, sum2, sumd; int onoff, ofd, slen; + ipfobj_t obj; ipnat_t *ipn; nat_t *nat; @@ -140,8 +151,12 @@ char *extif; nat->nat_p = IPPROTO_TCP; nat->nat_dir = NAT_OUTBOUND; if ((extif != NULL) && (*extif != '\0')) { - strncpy(nat->nat_ifname, extif, sizeof(nat->nat_ifname)); - nat->nat_ifname[sizeof(nat->nat_ifname) - 1] = '\0'; + strncpy(nat->nat_ifnames[0], extif, + sizeof(nat->nat_ifnames[0])); + strncpy(nat->nat_ifnames[1], extif, + sizeof(nat->nat_ifnames[1])); + nat->nat_ifnames[0][sizeof(nat->nat_ifnames[0]) - 1] = '\0'; + nat->nat_ifnames[1][sizeof(nat->nat_ifnames[1]) - 1] = '\0'; } ofd = socket(AF_INET, SOCK_DGRAM, 0); @@ -186,9 +201,15 @@ printf("local port# to use: %d\n", ntohs(usin.sin_port)); nat->nat_flags = IPN_TCPUDP; + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(*nsp); + obj.ipfo_ptr = nsp; + obj.ipfo_type = IPFOBJ_NATSAVE; + onoff = 1; if (ioctl(fd, SIOCSTLCK, &onoff) == 0) { - if (ioctl(fd, SIOCSTPUT, &nsp) != 0) + if (ioctl(fd, SIOCSTPUT, &obj) != 0) perror("SIOCSTPUT"); onoff = 0; if (ioctl(fd, SIOCSTLCK, &onoff) != 0) diff --git a/contrib/ipfilter/samples/relay.c b/contrib/ipfilter/samples/relay.c new file mode 100644 index 000000000000..b91779a4a8e4 --- /dev/null +++ b/contrib/ipfilter/samples/relay.c @@ -0,0 +1,196 @@ +/* $NetBSD$ */ + +/* + * Sample program to be used as a transparent proxy. + * + * Must be executed with permission enough to do an ioctl on /dev/ipl + * or equivalent. This is just a sample and is only alpha quality. + * - Darren Reed (8 April 1996) + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ip_compat.h" +#include "ip_fil.h" +#include "ip_nat.h" +#include "ipl.h" + +#define RELAY_BUFSZ 8192 + +char ibuff[RELAY_BUFSZ]; +char obuff[RELAY_BUFSZ]; + +int relay(ifd, ofd, rfd) +int ifd, ofd, rfd; +{ + fd_set rfds, wfds; + char *irh, *irt, *rrh, *rrt; + char *iwh, *iwt, *rwh, *rwt; + int nfd, n, rw; + + irh = irt = ibuff; + iwh = iwt = obuff; + nfd = ifd; + if (nfd < ofd) + nfd = ofd; + if (nfd < rfd) + nfd = rfd; + + while (1) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + if (irh > irt) + FD_SET(rfd, &wfds); + if (irh < (ibuff + RELAY_BUFSZ)) + FD_SET(ifd, &rfds); + if (iwh > iwt) + FD_SET(ofd, &wfds); + if (iwh < (obuff + RELAY_BUFSZ)) + FD_SET(rfd, &rfds); + + switch ((n = select(nfd + 1, &rfds, &wfds, NULL, NULL))) + { + case -1 : + case 0 : + return -1; + default : + if (FD_ISSET(ifd, &rfds)) { + rw = read(ifd, irh, ibuff + RELAY_BUFSZ - irh); + if (rw == -1) + return -1; + if (rw == 0) + return 0; + irh += rw; + n--; + } + if (n && FD_ISSET(ofd, &wfds)) { + rw = write(ofd, iwt, iwh - iwt); + if (rw == -1) + return -1; + iwt += rw; + n--; + } + if (n && FD_ISSET(rfd, &rfds)) { + rw = read(rfd, iwh, obuff + RELAY_BUFSZ - iwh); + if (rw == -1) + return -1; + if (rw == 0) + return 0; + iwh += rw; + n--; + } + if (n && FD_ISSET(rfd, &wfds)) { + rw = write(rfd, irt, irh - irt); + if (rw == -1) + return -1; + irt += rw; + n--; + } + if (irh == irt) + irh = irt = ibuff; + if (iwh == iwt) + iwh = iwt = obuff; + } + } +} + +main(argc, argv) +int argc; +char *argv[]; +{ + struct sockaddr_in sin; + ipfobj_t obj; + natlookup_t nl; + natlookup_t *nlp = &nl; + int fd, sl = sizeof(sl), se; + + openlog(argv[0], LOG_PID|LOG_NDELAY, LOG_DAEMON); + if ((fd = open(IPNAT_NAME, O_RDONLY)) == -1) { + se = errno; + perror("open"); + errno = se; + syslog(LOG_ERR, "open: %m\n"); + exit(-1); + } + + bzero(&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(nl); + obj.ipfo_ptr = &nl; + obj.ipfo_type = IPFOBJ_NATLOOKUP; + + bzero(&nl, sizeof(nl)); + nl.nl_flags = IPN_TCP; + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sl = sizeof(sin); + if (getsockname(0, (struct sockaddr *)&sin, &sl) == -1) { + se = errno; + perror("getsockname"); + errno = se; + syslog(LOG_ERR, "getsockname: %m\n"); + exit(-1); + } else { + nl.nl_inip.s_addr = sin.sin_addr.s_addr; + nl.nl_inport = sin.sin_port; + } + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sl = sizeof(sin); + if (getpeername(0, (struct sockaddr *)&sin, &sl) == -1) { + se = errno; + perror("getpeername"); + errno = se; + syslog(LOG_ERR, "getpeername: %m\n"); + exit(-1); + } else { + nl.nl_outip.s_addr = sin.sin_addr.s_addr; + nl.nl_outport = sin.sin_port; + } + + if (ioctl(fd, SIOCGNATL, &obj) == -1) { + se = errno; + perror("ioctl"); + errno = se; + syslog(LOG_ERR, "ioctl: %m\n"); + exit(-1); + } + + sin.sin_port = nl.nl_realport; + sin.sin_addr = nl.nl_realip; + sl = sizeof(sin); + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (connect(fd, (struct sockaddr *)&sin, sl) == -1) { + se = errno; + perror("connect"); + errno = se; + syslog(LOG_ERR, "connect: %m\n"); + exit(-1); + } + + (void) ioctl(fd, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); + (void) ioctl(0, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); + (void) ioctl(1, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); + + syslog(LOG_NOTICE, "connected to %s,%d\n", inet_ntoa(sin.sin_addr), + ntohs(sin.sin_port)); + if (relay(0, 1, fd) == -1) { + se = errno; + perror("relay"); + errno = se; + syslog(LOG_ERR, "relay: %m\n"); + exit(-1); + } + exit(0); +} diff --git a/contrib/ipfilter/samples/userauth.c b/contrib/ipfilter/samples/userauth.c index 5b50a94afd2e..ef059ac00250 100644 --- a/contrib/ipfilter/samples/userauth.c +++ b/contrib/ipfilter/samples/userauth.c @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + #include #include #include @@ -21,7 +23,9 @@ main() char yn[16]; int fd; - fd = open(IPL_AUTH, O_RDWR); + fd = open(IPL_NAME, O_RDWR); + fra.fra_len = 0; + fra.fra_buf = NULL; while (ioctl(fd, SIOCAUTHW, &frap) == 0) { if (fra.fra_info.fin_out) fra.fra_pass = FR_OUTQUE; @@ -29,10 +33,10 @@ main() fra.fra_pass = FR_INQUE; printf("%s ", inet_ntoa(fi->fi_src)); - if (fi->fi_fl & FI_TCPUDP) + if (fi->fi_flx & FI_TCPUDP) printf("port %d ", fin->fin_data[0]); printf("-> %s ", inet_ntoa(fi->fi_dst)); - if (fi->fi_fl & FI_TCPUDP) + if (fi->fi_flx & FI_TCPUDP) printf("port %d ", fin->fin_data[1]); printf("\n"); printf("Allow packet through ? [y/n]"); @@ -44,7 +48,7 @@ main() fra.fra_pass |= FR_BLOCK; else if (yn[0] == 'y' || yn[0] == 'Y') { fra.fra_pass |= FR_PASS; - if (fra.fra_info.fin_fi.fi_fl & FI_TCPUDP) + if (fra.fra_info.fin_fi.fi_flx & FI_TCPUDP) fra.fra_pass |= FR_KEEPSTATE; } else fra.fra_pass |= FR_NOMATCH; diff --git a/contrib/ipfilter/snoop.h b/contrib/ipfilter/snoop.h index 2f6c305d22bc..12dea374029b 100644 --- a/contrib/ipfilter/snoop.h +++ b/contrib/ipfilter/snoop.h @@ -1,3 +1,5 @@ +/* $NetBSD$ */ + /* * Copyright (C) 1993-2001 by Darren Reed. * @@ -9,7 +11,7 @@ /* * written to comply with the RFC (1761) from Sun. - * $Id: snoop.h,v 2.2.2.1 2001/06/26 10:43:20 darrenr Exp $ + * Id: snoop.h,v 2.3 2001/06/09 17:09:23 darrenr Exp */ struct snoophdr { char s_id[8]; diff --git a/contrib/ipfilter/test/.cvsignore b/contrib/ipfilter/test/.cvsignore new file mode 100644 index 000000000000..5825abcde9c7 --- /dev/null +++ b/contrib/ipfilter/test/.cvsignore @@ -0,0 +1,87 @@ +results +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +i1 +i2 +i3 +i4 +i5 +i6 +i7 +i8 +i9 +i10 +i11 +f1 +f2 +f3 +f4 +f5 +f6 +f7 +f8 +f9 +f10 +f11 +f12 +f13 +f14 +n1 +n2 +n3 +n4 +n5 +n6 +n7 +f15 +f16 +ipv6.1 +ipv6.2 +l1 +ni1 +ni2 +ni3 +ni4 +f17 +in1 +in2 +in3 +in4 +p1 +p2 +i12 +ip1 +p3 +i13 +ni5 +ni6 +i14 +in5 +ipv6.3 +n8 +n9 +n10 +n11 +ni7 +ni8 +ni9 +ni10 +ni11 +ni12 +n12 +in6 +i15 +ni13 +ni14 +ni15 +ni16 diff --git a/contrib/ipfilter/test/Makefile b/contrib/ipfilter/test/Makefile index a7a6c29fbf92..7f17241b3f23 100644 --- a/contrib/ipfilter/test/Makefile +++ b/contrib/ipfilter/test/Makefile @@ -1,15 +1,21 @@ # # (C)opyright 1993-1996 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/local/bin SBINDEST=/sbin MANDIR=/usr/share/man +all: results tests -tests: first 0 ftests ptests ntests nitests logtests ipv6 intests +results: + mkdir -p results + +tests: ipf nat logtests ipv6 pools + +ipf: ftests ptests + +nat: ntests nitests intests first: -mkdir -p results @@ -18,57 +24,70 @@ first: ftests: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 # Rule parsing tests -ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 +ptests: i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 -ntests: n1 n2 n3 n4 n5 n6 n7 +ntests: n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 -nitests: ni1 ni2 ni3 ni4 ni5 +nitests: ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 ni16 -intests: in1 in2 in3 in4 +intests: in1 in2 in3 in4 in5 in6 logtests: l1 +pools: p1 p2 p3 ip1 + ipv6: ipv6.1 ipv6.2 ipv6.3 -0: - @(cd ..; make ipftest; ) +bpf: bpf1 bpf-f1 -f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f14: - @/bin/sh ./dotest $@ +f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14: + @/bin/sh ./dotest `awk "/^$@ / { print; } " test.format` -f12 f13: - @/bin/sh ./hextest $@ +f15 f16 f17: + @/bin/sh ./mtest `awk "/^$@ / { print; } " test.format` -f15 f16: - @/bin/sh ./mtest $@ +i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 bpf1: + @/bin/sh ./itest `awk "/^$@ / { print; } " test.format` -f17: - @/bin/sh ./mhtest $@ +n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12: + @/bin/sh ./nattest `awk "/^$@ / { print; } " test.format` -i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12: - @/bin/sh ./itest $@ +ni1 ni2 ni3 ni4 ni5 ni7 ni8 ni9 ni10 ni11 ni12 ni13 ni14 ni15 ni16: + @/bin/sh ./natipftest single `awk "/^$@ / { print; } " test.format` -n1 n2 n3 n4 n5 n6 n7: - @/bin/sh ./nattest $@ +ni6: + @/bin/sh ./natipftest multi `awk "/^$@ / { print; } " test.format` -ni1 ni2 ni3 ni4 ni5 ni7 ni8 ni10 ni11: - @/bin/sh ./natipftest $@ - -in1 in2 in3 in4: - @/bin/sh ./intest $@ +in1 in2 in3 in4 in5 in6: + @/bin/sh ./intest `awk "/^$@ / { print; } " test.format` l1: - @/bin/sh ./logtest $@ + @/bin/sh ./logtest `awk "/^$@ / { print; } " test.format` ipv6.1 ipv6.2 ipv6.3: - @/bin/sh ./dotest6 $@ + @/bin/sh ./dotest6 `awk "/^$@ / { print; } " test.format` + +p1 p2 p3: + @/bin/sh ./ptest `awk "/^$@ / { print; } " test.format` + +ip1: + @/bin/sh ./iptest `awk "/^$@ / { print; } " test.format` + +bpf-f1: + /bin/sh ./bpftest `awk "/^$@ / { print; } " test.format` clean: - /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f13 f12 f14 f15 f16 f17 - /bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 - /bin/rm -f n1 n2 n3 n4 n5 n6 n7 - /bin/rm -f ni1 ni2 ni3 ni4 ni5 - /bin/rm -f in1 in2 in3 in4 + /bin/rm -f f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 + /bin/rm -f i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 + /bin/rm -f n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11 n12 + /bin/rm -f ni1 ni2 ni3 ni4 ni5 ni6 ni7 ni8 ni9 + /bin/rm -f ni10 ni11 ni12 ni13 ni14 ni15 ni16 + /bin/rm -f in1 in2 in3 in4 in5 in6 + /bin/rm -f p1 p2 p3 ip1 /bin/rm -f l1 /bin/rm -f ipv6.1 ipv6.2 ipv6.3 - /bin/rm -f results/* + /bin/rm -f bpf1 bpf-f1 + /bin/rm -f results/* logout + +diffs: + -cd expected; for i in *; do if [ -f $$i -a ! -f ../$$i -a -f ../results/$$i ] ; then diff -c $$i ../results/$$i >> ../diff.out; fi done diff --git a/contrib/ipfilter/test/bpftest b/contrib/ipfilter/test/bpftest new file mode 100644 index 000000000000..b24c0f16ae49 --- /dev/null +++ b/contrib/ipfilter/test/bpftest @@ -0,0 +1,28 @@ +#!/bin/sh +if [ -f /usr/ucb/touch ] ; then + TOUCH=/usr/ucb/touch +else + if [ -f /usr/bin/touch ] ; then + TOUCH=/usr/bin/touch + else + if [ -f /bin/touch ] ; then + TOUCH=/bin/touch + fi + fi +fi +echo "$1..."; +input=`expr $1 : 'bpf-\(.*\)'` +/bin/cp /dev/null results/$1 +( while read rule; do + echo "$rule" | ../ipftest -Rbr - -i input/$input >> results/$1; + if [ $? -ne 0 ] ; then + exit 1; + fi + echo "--------" >> results/$1 +done ) < regress/$1 +cmp expected/$1 results/$1 +status=$? +if [ $status = 0 ] ; then + $TOUCH $1 +fi +exit $status diff --git a/contrib/ipfilter/test/dotest b/contrib/ipfilter/test/dotest index 5a11605dea6a..71c8cceefc9f 100644 --- a/contrib/ipfilter/test/dotest +++ b/contrib/ipfilter/test/dotest @@ -1,4 +1,5 @@ #!/bin/sh +format=$2 if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -13,7 +14,7 @@ fi echo "$1..."; /bin/cp /dev/null results/$1 ( while read rule; do - echo "$rule" | ../ipftest -br - -i input/$1 >> results/$1; + echo "$rule" | ../ipftest -F $format -Rbr - -i input/$1 >> results/$1; if [ $? -ne 0 ] ; then exit 1; fi diff --git a/contrib/ipfilter/test/dotest6 b/contrib/ipfilter/test/dotest6 index 297de6f7f374..d6db564ebee2 100755 --- a/contrib/ipfilter/test/dotest6 +++ b/contrib/ipfilter/test/dotest6 @@ -1,4 +1,6 @@ #!/bin/sh +format=$2 +mkdir -p results if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -19,7 +21,7 @@ if [ $? -ne 0 ] ; then exit 0 fi ( while read rule; do - echo "$rule" | ../ipftest -6Hbr - -i input/$1 >> results/$1; + echo "$rule" | ../ipftest -F $format -6br - -i input/$1 >> results/$1; if [ $? -ne 0 ] ; then exit 1; fi diff --git a/contrib/ipfilter/test/expected/bpf-f1 b/contrib/ipfilter/test/expected/bpf-f1 new file mode 100644 index 000000000000..85ce84c9f693 --- /dev/null +++ b/contrib/ipfilter/test/expected/bpf-f1 @@ -0,0 +1,20 @@ +nomatch +pass +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +pass +-------- +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/ipfilter/test/expected/bpf1 b/contrib/ipfilter/test/expected/bpf1 new file mode 100644 index 000000000000..9d0ad1b06b92 --- /dev/null +++ b/contrib/ipfilter/test/expected/bpf1 @@ -0,0 +1,4 @@ +pass in bpf { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass in bpf { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } diff --git a/contrib/ipfilter/test/expected/f17 b/contrib/ipfilter/test/expected/f17 index 99eee84d78fb..4fe3acf5764d 100644 --- a/contrib/ipfilter/test/expected/f17 +++ b/contrib/ipfilter/test/expected/f17 @@ -3,8 +3,4 @@ block return-rst pass pass pass -pass -pass -pass -pass -------- diff --git a/contrib/ipfilter/test/expected/i1 b/contrib/ipfilter/test/expected/i1 index 3eb14be74356..93530f9f575a 100644 --- a/contrib/ipfilter/test/expected/i1 +++ b/contrib/ipfilter/test/expected/i1 @@ -1,7 +1,7 @@ -pass in from any to any -block out from any to any -log in from any to any -log body in from any to any +pass in all +block out all +log in all +log body in all count in from any to any pass in from !any to any block in from any to !any @@ -11,3 +11,5 @@ pass in log body quick from any to any block return-rst in quick on le0(!) proto tcp from any to any block return-icmp in on qe0(!) from any to any block return-icmp(host-unr) in on qe0(!) from any to any +block return-icmp-as-dest(port-unr) in on qe0(!) from any to any +pass out on longNICname0(!) from 254.220.186.152/32 to 254.220.186.152/32 diff --git a/contrib/ipfilter/test/expected/i11 b/contrib/ipfilter/test/expected/i11 index ddf800051aff..058d03ac01cb 100644 --- a/contrib/ipfilter/test/expected/i11 +++ b/contrib/ipfilter/test/expected/i11 @@ -1,5 +1,8 @@ pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 keep state block in log first on lo0(!) proto tcp/udp from any to any keep state -pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 2049 keep frags +pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 20499 keep frags pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 53 keep state keep frags -pass in proto tcp from any port > 1024 to 127.0.0.1/32 port = 25 keep state +pass in on ed0(!) out-via vx0(!) proto udp from any to any keep state +pass out on ppp0(!) in-via le0(!) proto tcp from any to any keep state +pass in proto tcp from any port > 1024 to 127.0.0.1/32 port = 1024 keep state +pass in proto tcp from any to any flags S/FSRPAU keep state (limit 101,strict,newisn,no-icmp-err) diff --git a/contrib/ipfilter/test/expected/i12 b/contrib/ipfilter/test/expected/i12 index 2a904a31746b..22a348871bf6 100644 --- a/contrib/ipfilter/test/expected/i12 +++ b/contrib/ipfilter/test/expected/i12 @@ -1,4 +1,34 @@ -block in on eri0(!) from any to any head 1 -pass in on eri0(!) proto icmp from any to any group 1 -pass out on ed0(!) from any to any head 1000000 -block out on ed0(!) proto udp from any to any group 1000000 +pass in from 1.1.1.1/32 to 2.2.2.2/32 +pass in from 2.2.2.0/24 to 4.4.4.4/32 +pass in from 3.3.3.3/32 to 4.4.4.4/32 +pass in from 2.2.2.0/24 to 5.5.5.5/32 +pass in from 3.3.3.3/32 to 5.5.5.5/32 +pass in from 2.2.2.0/24 to 6.6.6.6/32 +pass in from 3.3.3.3/32 to 6.6.6.6/32 +pass in from 2.2.2.0/24 to 5.5.5.5/32 port = 22 +pass in from 3.3.3.3/32 to 5.5.5.5/32 port = 22 +pass in from 2.2.2.0/24 to 6.6.6.6/32 port = 22 +pass in from 3.3.3.3/32 to 6.6.6.6/32 port = 22 +pass in from 2.2.2.0/24 to 5.5.5.5/32 port = 25 +pass in from 3.3.3.3/32 to 5.5.5.5/32 port = 25 +pass in from 2.2.2.0/24 to 6.6.6.6/32 port = 25 +pass in from 3.3.3.3/32 to 6.6.6.6/32 port = 25 +pass in proto tcp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 +pass in proto tcp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 +pass in proto tcp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 +pass in proto tcp from 3.3.3.3/32 to 6.6.6.6/32 port = 53 +pass in proto tcp from 2.2.2.0/24 to 5.5.5.5/32 port = 9 +pass in proto tcp from 3.3.3.3/32 to 5.5.5.5/32 port = 9 +pass in proto tcp from 2.2.2.0/24 to 6.6.6.6/32 port = 9 +pass in proto tcp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 +pass in proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 +pass in proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 +pass in proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 +pass in proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 53 +pass in proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 9 +pass in proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 9 +pass in proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 9 +pass in proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 +pass in from 10.10.10.10/32 to 11.11.11.11/32 +pass in from pool/101(!) to hash/202(!) +pass in from hash/303(!) to pool/404(!) diff --git a/contrib/ipfilter/test/expected/i13 b/contrib/ipfilter/test/expected/i13 new file mode 100644 index 000000000000..5c8d94532b9c --- /dev/null +++ b/contrib/ipfilter/test/expected/i13 @@ -0,0 +1,2 @@ +block in from any to any +pass in from any to any diff --git a/contrib/ipfilter/test/expected/i14 b/contrib/ipfilter/test/expected/i14 new file mode 100644 index 000000000000..5a10155b784f --- /dev/null +++ b/contrib/ipfilter/test/expected/i14 @@ -0,0 +1,8 @@ +block in on eri0(!) all head 1 +pass in on eri0(!) proto icmp from any to any group 1 +pass out on ed0(!) all head 1000000 +block out on ed0(!) proto udp from any to any group 1000000 +block in on vm0(!) proto tcp/udp from any to any head 101 +pass in proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group 101 +pass in proto tcp from 1.0.0.1/32 to 2.0.0.2/32 group 101 +pass in proto udp from 2.0.0.2/32 to 3.0.0.3/32 group 101 diff --git a/contrib/ipfilter/test/expected/i15 b/contrib/ipfilter/test/expected/i15 new file mode 100644 index 000000000000..49746598df02 --- /dev/null +++ b/contrib/ipfilter/test/expected/i15 @@ -0,0 +1,4 @@ +pass out on fxp0(!) all set-tag(log=100) +pass out on fxp0(!) all set-tag(nat=foo) +pass out on fxp0(!) all set-tag(log=100, nat=200) +pass out on fxp0(!) all set-tag(log=2147483648, nat=overtherainbowis) diff --git a/contrib/ipfilter/test/expected/i2 b/contrib/ipfilter/test/expected/i2 index 9d3398d3e11f..37ec9c485b50 100644 --- a/contrib/ipfilter/test/expected/i2 +++ b/contrib/ipfilter/test/expected/i2 @@ -1,6 +1,7 @@ log in proto tcp from any to any pass in proto tcp from any to any pass in proto udp from 127.0.0.1/32 to 127.0.0.1/32 +block in proto ipv6 from any to any block in proto udp from any to any block in proto 250 from any to any pass in proto tcp/udp from any to any diff --git a/contrib/ipfilter/test/expected/i3 b/contrib/ipfilter/test/expected/i3 index 18d91614f0a6..6150c7e55bd1 100644 --- a/contrib/ipfilter/test/expected/i3 +++ b/contrib/ipfilter/test/expected/i3 @@ -1,4 +1,5 @@ -log in from any to any +log in all +pass in from 128.16.0.0/16 to 129.10.10.0/24 pass in from 128.0.0.0/24 to 128.0.0.0/16 pass in from 128.0.0.0/24 to 128.0.0.0/16 pass in from 128.0.0.0/24 to 128.0.0.0/16 @@ -6,5 +7,5 @@ pass in from 128.0.0.0/24 to 128.0.0.0/16 pass in from 128.0.0.0/24 to 128.0.0.0/16 pass in from 127.0.0.1/32 to 127.0.0.1/32 block in log from any to any -block in log level auth.info on hme0(!) from any to any -log level local5.warn out from any to any +block in log level auth.info on hme0(!) all +log level local5.warn out all diff --git a/contrib/ipfilter/test/expected/i4 b/contrib/ipfilter/test/expected/i4 index dfa3674db2a6..89c0995f6e4d 100644 --- a/contrib/ipfilter/test/expected/i4 +++ b/contrib/ipfilter/test/expected/i4 @@ -2,6 +2,7 @@ log in proto tcp from any port > 0 to any log in proto tcp from any to any port > 0 pass in proto tcp from any port != 0 to any port 0 >< 65535 pass in proto udp from 127.0.0.1/32 port > 32000 to 127.0.0.1/32 port < 29000 -block in proto udp from any port != 123 to any port < 123 +block in proto udp from any port != 123 to any port < 7 block in proto tcp from any port = 25 to any port > 25 pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3 +pass in log first quick proto tcp from any port > 1023 to any port = 1723 flags S/FSRPAU keep state diff --git a/contrib/ipfilter/test/expected/i5 b/contrib/ipfilter/test/expected/i5 index 3bcb10bf205e..6947ad341719 100644 --- a/contrib/ipfilter/test/expected/i5 +++ b/contrib/ipfilter/test/expected/i5 @@ -1,4 +1,4 @@ -log in from any to any +log in all count in tos 0x80 from any to any pass in on ed0(!) tos 0x40 from 127.0.0.1/32 to 127.0.0.1/32 block in log on lo0(!) ttl 0 from any to any diff --git a/contrib/ipfilter/test/expected/i6 b/contrib/ipfilter/test/expected/i6 index 4849626fdcf0..40fe1857398b 100644 --- a/contrib/ipfilter/test/expected/i6 +++ b/contrib/ipfilter/test/expected/i6 @@ -1,4 +1,10 @@ pass in on lo0(!) fastroute from any to any +pass in on lo0(!) to qe0(!) from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) to qe0(!):127.0.0.1 from 127.0.0.1/32 to 127.0.0.1/32 pass in on lo0(!) dup-to qe0(!) from 127.0.0.1/32 to 127.0.0.1/32 -pass in on qe0(!) dup-to qe0(!):127.0.0.1 from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) dup-to qe0(!):127.0.0.1 from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) dup-to qe0(!):127.0.0.1 to hme0(!):10.1.1.1 from 127.0.0.1/32 to 127.0.0.1/32 block in quick on qe0(!) to qe1(!) from any to any +block in quick to qe1(!) from any to any +pass out quick dup-to hme0(!) from any to any +pass in quick fastroute all diff --git a/contrib/ipfilter/test/expected/i7 b/contrib/ipfilter/test/expected/i7 index db9cd0120bcb..c46364b558b1 100644 --- a/contrib/ipfilter/test/expected/i7 +++ b/contrib/ipfilter/test/expected/i7 @@ -1,4 +1,4 @@ pass in on ed0(!) proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 flags S/SA -block in on lo0(!) proto tcp from any to any flags A/FSRPAUC +block in on lo0(!) proto tcp from any to any flags A/FSRPAU pass in on lo0(!) proto tcp from any to any flags /SPA block in on lo0(!) proto tcp from any to any flags C/A diff --git a/contrib/ipfilter/test/expected/i9 b/contrib/ipfilter/test/expected/i9 index b36d864a6e5e..bae7c9bcce10 100644 --- a/contrib/ipfilter/test/expected/i9 +++ b/contrib/ipfilter/test/expected/i9 @@ -1,5 +1,7 @@ -pass in from 127.0.0.1/32 to 127.0.0.1/32 with short -block in from any to any with ipopt +pass in from 127.0.0.1/32 to 127.0.0.1/32 with short,frag +block in from any to any with ipopts pass in from any to any with opt nop,rr,zsu pass in from any to any with opt nop,rr,zsu not opt lsrr,ssrr pass in from 127.0.0.1/32 to 127.0.0.1/32 with not frag +pass in proto tcp from any to any flags S/FSRPAU with not oow keep state +pass in proto tcp from any to any flags S/FSRPAU with not bad,bad-src,bad-nat diff --git a/contrib/ipfilter/test/expected/in1 b/contrib/ipfilter/test/expected/in1 index c507db7c94d1..ce5a61003ec3 100644 --- a/contrib/ipfilter/test/expected/in1 +++ b/contrib/ipfilter/test/expected/in1 @@ -10,16 +10,18 @@ map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp/udp 30000:39999 map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp auto map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap udp auto map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp/udp auto -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port ftp ftp/tcp +map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port 21 ftp/tcp map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port 1010 ftp/tcp map le0 0.0.0.0/0 -> 0.0.0.0/32 frag map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 frag -map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port ftp ftp/tcp frag +map ppp0 192.168.0.0/16 -> 0.0.0.0/32 proxy port 21 ftp/tcp frag map le0 0.0.0.0/0 -> 0.0.0.0/32 age 10/10 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 age 10/20 map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 age 30/30 map le0 0.0.0.0/0 -> 0.0.0.0/32 frag age 10/10 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20 map ppp0 192.168.0.0/16 -> 0.0.0.0/32 portmap tcp 10000:19999 frag age 30/30 -map fxp0 from 192.168.0.0/18 to any port = ftp -> 1.2.3.4/32 proxy port ftp ftp/tcp +map fxp0 from 192.168.0.0/18 to any port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp +map thisisalonginte 0.0.0.0/0 -> 0.0.0.0/32 mssclamp 1452 tag freddyliveshere +map bar0 0.0.0.0/0 -> 0.0.0.0/32 icmpidmap icmp 1000:2000 diff --git a/contrib/ipfilter/test/expected/in2 b/contrib/ipfilter/test/expected/in2 index ebe747b13a36..61c0d1854dd5 100644 --- a/contrib/ipfilter/test/expected/in2 +++ b/contrib/ipfilter/test/expected/in2 @@ -1,22 +1,67 @@ -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 tcp -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 ip -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 tcp -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 ip -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 tcp -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 udp -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 tcp/udp -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 icmp -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 tcp round-robin -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 ip frag -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 icmp frag -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 tcp round-robin frag -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 ip frag age 10/10 -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 -rdr le0 0.0.0.0/0 port 0 -> 1.1.1.1 port 0 icmp frag age 10/10 -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 -rdr le0 0.0.0.0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp/udp +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 tag nattagcacheline +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555 tcp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port = 5555 tcp +rdr le0 0.0.0.0/0 -> 254.220.186.152 ip +rdr le0 0.0.0.0/0 -> 254.220.186.152,254.220.186.152 ip diff --git a/contrib/ipfilter/test/expected/in5 b/contrib/ipfilter/test/expected/in5 new file mode 100644 index 000000000000..7b3120a7c553 --- /dev/null +++ b/contrib/ipfilter/test/expected/in5 @@ -0,0 +1,22 @@ +rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 tcp +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 udp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp/udp +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 icmp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip frag +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 icmp frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/10 +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 ip frag age 10/20 +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 icmp frag age 10/10 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag age 20/20 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag age 30/30 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag age 40/40 diff --git a/contrib/ipfilter/test/expected/in6 b/contrib/ipfilter/test/expected/in6 new file mode 100644 index 000000000000..08bbff061c74 --- /dev/null +++ b/contrib/ipfilter/test/expected/in6 @@ -0,0 +1,3 @@ +map foo0 from any port = 1 to any port != 0 -> 0.0.0.0/32 udp +map foo0 from any port < 1 to any port > 0 -> 0.0.0.0/32 tcp +map foo0 from any port <= 1 to any port >= 0 -> 0.0.0.0/32 tcp/udp diff --git a/contrib/ipfilter/test/expected/ip1 b/contrib/ipfilter/test/expected/ip1 new file mode 100644 index 000000000000..b04fa9d1ad62 --- /dev/null +++ b/contrib/ipfilter/test/expected/ip1 @@ -0,0 +1,68 @@ +table role = ipf type = tree number = 1 + {; }; +table role = ipf type = tree number = 100 + { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; +table role = ipf type = tree number = 110 + { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; +table role = ipf type = tree number = 120 + { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; +table role = ipf type = tree number = 130 + { 2.2.2.0/24; ! 2.2.0.0/16; 1.2.3.4/32; }; +table role = ipf type = hash number = 2 size = 1 + {; }; +table role = ipf type = hash number = 200 size = 5 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 210 size = 5 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 220 size = 5 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 230 size = 5 + { 0/0; 4/32; 1.2.3.4/32; }; +table role = ipf type = hash number = 240 size = 5 seed = 101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 250 size = 5 seed = 101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 260 size = 5 seed = 101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 270 size = 5 seed = 101 + { 0/0; 4/32; 1.2.3.4/32; }; +table role = ipf type = hash number = 2000 size = 1001 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 2000 size = 1001 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 2000 size = 1001 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 2000 size = 1001 + { 0/0; 4/32; 1.2.3.4/32; }; +table role = ipf type = hash number = 100 size = 1001 seed = 101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 100 size = 1001 seed = 101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 100 size = 1001 seed = 101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 100 size = 1001 seed = 101 + { 0/0; 4/32; 1.2.3.4/32; }; +group-map in role = ipf number = 300 size = 5 + { 0/0, group = 303; 5/32, group = 303; 1.2.3.4/32, group = 303; }; +group-map in role = nat number = 300 size = 5 + { 0/0, group = 303; 6/32, group = 303; 1.2.3.4/32, group = 303; }; +group-map in role = auth number = 300 size = 5 + { 0/0, group = 303; 7/32, group = 303; 1.2.3.4/32, group = 303; }; +group-map in role = count number = 300 size = 5 + { 0/0, group = 303; 8/32, group = 303; 1.2.3.4/32, group = 303; }; +group-map out role = ipf number = 400 size = 5 + { 0/0, group = 303; 5/32, group = 303; 1.2.3.4/32, group = 606; }; +group-map out role = nat number = 400 size = 5 + { 0/0, group = 303; 6/32, group = 303; 1.2.3.4/32, group = 606; }; +group-map out role = auth number = 400 size = 5 + { 0/0, group = 303; 7/32, group = 303; 1.2.3.4/32, group = 606; }; +group-map out role = count number = 400 size = 5 + { 0/0, group = 303; 8/32, group = 303; 1.2.3.4/32, group = 606; }; +group-map in role = ipf number = 500 size = 5 + { 0/0, group = 10; 5/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = nat number = 500 size = 5 + { 0/0, group = 10; 6/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = auth number = 500 size = 5 + { 0/0, group = 10; 7/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = count number = 500 size = 5 + { 0/0, group = 10; 8/32, group = 800; 1.2.3.4/32, group = 606; }; diff --git a/contrib/ipfilter/test/expected/l1 b/contrib/ipfilter/test/expected/l1 index dbd6b012e4b5..ba0de69b9239 100644 --- a/contrib/ipfilter/test/expected/l1 +++ b/contrib/ipfilter/test/expected/l1 @@ -2,7 +2,7 @@ log in all 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN -01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -F IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN @@ -24,7 +24,7 @@ pass in log quick proto tcp from 1.1.1.1 to any flags S keep state 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN 01/01/1970 00:00:00.000000 e1 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT -01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -F K-S IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN -------- pass in log first quick proto tcp from 1.1.1.1 to any flags S keep state 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN @@ -34,7 +34,7 @@ pass in log first quick proto tcp from 1.1.1.1 to any flags S keep state 01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN 01/01/1970 00:00:00.000000 anon0 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN 01/01/1970 00:00:00.000000 e1 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT -01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -F K-S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN diff --git a/contrib/ipfilter/test/expected/l1.b b/contrib/ipfilter/test/expected/l1.b index e5c107759930..c060086d8df4 100644 --- a/contrib/ipfilter/test/expected/l1.b +++ b/contrib/ipfilter/test/expected/l1.b @@ -1,7 +1,7 @@ 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN -01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -F IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN @@ -20,7 +20,7 @@ 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN 01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN 01/01/1970 00:00:00.000000 e1 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT -01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -F K-S IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN -------- 01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN -------- @@ -29,7 +29,7 @@ 01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN 01/01/1970 00:00:00.000000 anon0 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN 01/01/1970 00:00:00.000000 e1 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT -01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -F K-S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN 01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN 01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN diff --git a/contrib/ipfilter/test/expected/n1 b/contrib/ipfilter/test/expected/n1 index c195f6f79263..0f87034649b8 100644 --- a/contrib/ipfilter/test/expected/n1 +++ b/contrib/ipfilter/test/expected/n1 @@ -19,7 +19,10 @@ ip 20(20) 255 10.1.1.2 > 10.3.4.5 ip 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 ip 48(20) 1 10.2.2.2 > 10.4.3.2 ip 48(20) 1 10.4.3.2 > 10.1.1.1 +ip 48(20) 1 10.4.3.2 > 10.3.4.1 +ip 48(20) 1 10.4.3.2 > 10.3.4.2 ip 48(20) 1 10.4.3.2 > 10.3.4.3 +ip 48(20) 1 10.4.3.2 > 10.3.4.4 ip 48(20) 1 10.4.3.2 > 10.3.4.5 ip 20(20) 34 10.1.1.2 > 10.4.3.2 ip 20(20) 34 10.4.3.2 > 10.3.4.4 @@ -51,7 +54,10 @@ ip 20(20) 255 10.1.1.2 > 10.1.1.0 ip 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 ip 48(20) 1 10.3.4.5 > 10.4.3.2 ip 48(20) 1 10.4.3.2 > 10.2.2.2 +ip 48(20) 1 10.4.3.2 > 10.3.4.1 +ip 48(20) 1 10.4.3.2 > 10.3.4.2 ip 48(20) 1 10.4.3.2 > 10.3.4.3 +ip 48(20) 1 10.4.3.2 > 10.3.4.4 ip 48(20) 1 10.4.3.2 > 10.1.1.1 ip 20(20) 34 10.3.4.5 > 10.4.3.2 ip 20(20) 34 10.4.3.2 > 10.3.4.4 @@ -81,9 +87,12 @@ ip 20(20) 255 10.1.1.0 > 10.3.4.5 ip 20(20) 255 10.1.1.1 > 10.3.4.5 ip 20(20) 255 10.1.1.2 > 10.3.4.5 ip 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 -ip 48(20) 1 10.3.4.2 > 10.4.3.2 +ip 48(20) 1 10.3.4.3 > 10.4.3.2 ip 48(20) 1 10.4.3.2 > 10.2.2.2 -ip 48(20) 1 10.4.3.2 > 10.3.4.3 +ip 48(20) 1 10.4.3.2 > 10.3.4.1 +ip 48(20) 1 10.4.3.2 > 10.3.4.2 +ip 48(20) 1 10.4.3.2 > 10.1.1.1 +ip 48(20) 1 10.4.3.2 > 10.3.4.4 ip 48(20) 1 10.4.3.2 > 10.3.4.5 ip 20(20) 34 10.3.4.3 > 10.4.3.2 ip 20(20) 34 10.4.3.2 > 10.3.4.4 diff --git a/contrib/ipfilter/test/expected/n10 b/contrib/ipfilter/test/expected/n10 new file mode 100644 index 000000000000..f30d7573bec5 --- /dev/null +++ b/contrib/ipfilter/test/expected/n10 @@ -0,0 +1,6 @@ +4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 655d 0000 0204 0064 +------------------------------- +4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 61d9 0000 0204 03e8 +------------------------------- +4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 600d 0000 0204 05b4 +------------------------------- diff --git a/contrib/ipfilter/test/expected/n11 b/contrib/ipfilter/test/expected/n11 new file mode 100644 index 000000000000..3732709e6727 --- /dev/null +++ b/contrib/ipfilter/test/expected/n11 @@ -0,0 +1,51 @@ +ip 20(20) 255 10.1.1.0 > 10.1.1.2 +ip 20(20) 255 1.6.7.8 > 10.1.1.2 +ip 20(20) 255 10.1.1.2 > 10.1.1.1 +ip 20(20) 255 10.2.2.1 > 10.1.2.1 +ip 20(20) 255 10.2.2.2 > 10.1.2.1 +ip 20(20) 255 10.1.1.1 > 10.1.1.2 +ip 20(20) 255 10.1.1.2 > 10.1.1.1 +ip 20(20) 255 10.2.2.1 > 10.2.1.1 +ip 20(20) 255 10.2.2.2 > 10.2.1.1 +ip 20(20) 255 10.2.2.3 > 10.1.1.1 +ip 20(20) 255 10.2.3.4 > 10.2.2.2 +ip 20(20) 255 10.1.1.1 > 10.2.2.2 +ip 20(20) 255 10.1.1.2 > 10.2.2.2 +ip 20(20) 255 10.1.1.0 > 10.3.4.5 +ip 20(20) 255 10.1.1.1 > 10.3.4.5 +ip 20(20) 255 10.1.1.2 > 10.3.4.5 +------------------------------- +ip 20(20) 255 10.2.2.2 > 10.1.1.2 +ip 20(20) 255 10.1.1.1 > 10.1.1.2 +ip 20(20) 255 10.2.2.2 > 10.1.1.1 +ip 20(20) 255 10.2.2.1 > 10.1.2.1 +ip 20(20) 255 10.2.2.2 > 10.1.2.1 +ip 20(20) 255 10.1.1.1 > 10.1.1.2 +ip 20(20) 255 10.1.1.2 > 10.1.1.1 +ip 20(20) 255 10.2.2.1 > 10.2.1.1 +ip 20(20) 255 10.2.2.2 > 10.2.1.1 +ip 20(20) 255 10.2.2.3 > 10.1.1.1 +ip 20(20) 255 10.2.3.4 > 10.1.1.0 +ip 20(20) 255 10.1.1.1 > 10.1.1.2 +ip 20(20) 255 10.1.1.2 > 10.1.1.0 +ip 20(20) 255 10.1.1.0 > 10.3.4.5 +ip 20(20) 255 10.1.1.1 > 10.3.4.5 +ip 20(20) 255 10.1.1.2 > 10.3.4.5 +------------------------------- +ip 20(20) 255 10.3.4.0 > 10.1.1.2 +ip 20(20) 255 10.3.4.1 > 10.1.1.2 +ip 20(20) 255 10.3.4.2 > 10.1.1.1 +ip 20(20) 255 10.2.2.1 > 10.1.2.1 +ip 20(20) 255 10.2.2.2 > 10.1.2.1 +ip 20(20) 255 10.1.1.1 > 10.1.1.2 +ip 20(20) 255 10.1.1.2 > 10.1.1.1 +ip 20(20) 255 10.2.2.1 > 10.2.1.1 +ip 20(20) 255 10.2.2.2 > 10.2.1.1 +ip 20(20) 255 10.2.2.3 > 10.1.1.1 +ip 20(20) 255 10.2.3.4 > 10.2.2.2 +ip 20(20) 255 10.1.1.1 > 10.2.2.2 +ip 20(20) 255 10.1.1.2 > 10.2.2.2 +ip 20(20) 255 10.1.1.0 > 10.1.1.5 +ip 20(20) 255 10.1.1.1 > 10.1.1.5 +ip 20(20) 255 10.1.1.2 > 10.1.1.5 +------------------------------- diff --git a/contrib/ipfilter/test/expected/n12 b/contrib/ipfilter/test/expected/n12 new file mode 100644 index 000000000000..010b77b63e15 --- /dev/null +++ b/contrib/ipfilter/test/expected/n12 @@ -0,0 +1,4 @@ +4510 0040 2020 4000 4006 9478 c0a8 01bc c0a8 0303 2710 0017 4e33 298e 0000 0000 b002 4000 6ff8 0000 0204 05b4 0101 0402 0103 0300 0101 080a 0c72 549e 0000 0000 +4500 003c 00b0 4000 fe06 7964 c0a8 0303 c0a8 7e53 0017 12c2 f674 e02c 4e33 298f a012 2798 7ace 0000 0101 080a 2c05 b797 0c72 549e 0103 0300 0204 05b4 +4510 0034 493b 4000 4006 6b69 c0a8 01bc c0a8 0303 2710 0017 4e33 298f f674 e02d 8010 4000 f673 0000 0101 080a 0c72 549e 2c05 b797 +------------------------------- diff --git a/contrib/ipfilter/test/expected/n4 b/contrib/ipfilter/test/expected/n4 index c6fb4d4e42f5..8cdf78c31843 100644 --- a/contrib/ipfilter/test/expected/n4 +++ b/contrib/ipfilter/test/expected/n4 @@ -1,30 +1,66 @@ ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +ip 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 ip 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +ip 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +ip 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 ------------------------------- ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +ip 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 ip 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +ip 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +ip 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 ------------------------------- ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +ip 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +ip 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12346 > 10.2.2.1,10023 +ip 40(20) 6 10.1.0.0,23 > 10.3.3.3,12346 ip 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +ip 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +ip 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 ------------------------------- ip 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 -ip 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 ip 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 +ip 28(20) 17 10.1.1.0,53 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +ip 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 ------------------------------- ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 -ip 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 ip 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +ip 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +ip 40(20) 6 10.1.1.0,53 > 10.3.3.3,12345 +------------------------------- +ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +ip 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +ip 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +ip 28(20) 17 10.3.3.3,12345 > 10.2.2.1,53 +ip 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +ip 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +ip 40(20) 6 10.1.1.0,53 > 10.3.3.3,12345 ------------------------------- diff --git a/contrib/ipfilter/test/expected/n5 b/contrib/ipfilter/test/expected/n5 index 75f174b0741c..521c7376ef45 100644 --- a/contrib/ipfilter/test/expected/n5 +++ b/contrib/ipfilter/test/expected/n5 @@ -154,11 +154,11 @@ ip 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 ip 20(20) 0 10.1.1.1 > 10.1.1.2 ip 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 ip 20(20) 0 10.1.1.2 > 10.1.1.1 -ip 40(20) 6 10.3.4.1,1026 > 10.3.4.5,40000 +ip 40(20) 6 10.3.4.3,1026 > 10.3.4.5,40000 ip 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 -ip 40(20) 6 10.3.4.1,1025 > 10.3.4.5,40000 +ip 40(20) 6 10.3.4.3,1025 > 10.3.4.5,40000 ip 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 -ip 28(20) 17 10.3.4.1,1025 > 10.3.4.5,40001 +ip 28(20) 17 10.3.4.3,1025 > 10.3.4.5,40001 ip 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 ip 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 ip 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 diff --git a/contrib/ipfilter/test/expected/n7 b/contrib/ipfilter/test/expected/n7 index 51aa987c2da6..db8bb5078018 100644 --- a/contrib/ipfilter/test/expected/n7 +++ b/contrib/ipfilter/test/expected/n7 @@ -9,6 +9,16 @@ ip 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 ip 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 ------------------------------- ip 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +ip 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 +ip 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10023 +ip 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10023 +ip 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 +ip 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 +ip 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 +ip 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 +ip 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +------------------------------- +ip 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 ip 40(20) 6 10.2.3.1,1231 > 10.1.1.1,23 ip 40(20) 6 10.2.3.1,1232 > 10.1.1.1,50 ip 40(20) 6 10.2.3.1,1233 > 10.1.1.1,79 diff --git a/contrib/ipfilter/test/expected/n8 b/contrib/ipfilter/test/expected/n8 new file mode 100644 index 000000000000..7a26a26a6513 --- /dev/null +++ b/contrib/ipfilter/test/expected/n8 @@ -0,0 +1,5 @@ +4500 0054 8bc1 0000 ff01 13d5 0a0a 0a01 0404 0404 0800 efdf 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7df 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +4500 0054 8bc1 0000 ff01 13d5 0a0a 0a01 0404 0404 0800 efde 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +------------------------------- diff --git a/contrib/ipfilter/test/expected/n9 b/contrib/ipfilter/test/expected/n9 new file mode 100644 index 000000000000..39979fa55fff --- /dev/null +++ b/contrib/ipfilter/test/expected/n9 @@ -0,0 +1,5 @@ +4500 0054 8bc1 0000 ff01 17d9 0202 0202 0a0a 0a01 0800 efdf 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7df 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +4500 0054 8bc1 0000 ff01 17d9 0202 0202 0a0a 0a01 0800 efde 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni1 b/contrib/ipfilter/test/expected/ni1 index 724d38eef74b..be981f1e10b0 100644 --- a/contrib/ipfilter/test/expected/ni1 +++ b/contrib/ipfilter/test/expected/ni1 @@ -1,4 +1,4 @@ -4500 0028 4706 4000 0111 1eac 0606 0606 0404 0404 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 -4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0b00 5773 0000 0000 4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 afc9 829e 0014 6b10 -4500 0044 809a 0000 ff01 3115 0303 0303 0202 0202 0b00 0131 0000 0000 4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 afc9 829e 0014 6b10 0402 0000 3be5 468d 000a cfc3 +4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0b00 5773 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 afc9 829e 0014 6b10 +4500 0044 809a 0000 ff01 3115 0303 0303 0202 0202 0b00 0131 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 afc9 829e 0014 6b10 0402 0000 3be5 468d 000a cfc3 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni10 b/contrib/ipfilter/test/expected/ni10 index e7845812b2c6..df7b03f83fee 100644 --- a/contrib/ipfilter/test/expected/ni10 +++ b/contrib/ipfilter/test/expected/ni10 @@ -1,5 +1,5 @@ -4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2f1f 0202 0202 0404 0404 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 5000 0050 0000 0001 -4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 0303 113f 0000 0000 4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28ab 0404 0404 0202 0201 5000 0050 0000 0001 +4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 0000 0000 ff01 afb9 0202 0202 0404 0404 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 5000 0050 0000 0001 +4500 0058 0001 0000 ff01 af98 0202 0202 0404 0404 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28ab 0404 0404 0202 0201 5000 0050 0000 0001 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni11 b/contrib/ipfilter/test/expected/ni11 index 8cc37f44f289..d6db012a2ab0 100644 --- a/contrib/ipfilter/test/expected/ni11 +++ b/contrib/ipfilter/test/expected/ni11 @@ -1,5 +1,5 @@ -4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 271f 0a02 0202 0404 0404 0303 a7fb 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 -4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 0303 0735 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fb 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 +4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni12 b/contrib/ipfilter/test/expected/ni12 new file mode 100644 index 000000000000..70f991b8397e --- /dev/null +++ b/contrib/ipfilter/test/expected/ni12 @@ -0,0 +1,5 @@ +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 0303 0735 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni13 b/contrib/ipfilter/test/expected/ni13 new file mode 100644 index 000000000000..3848d395956d --- /dev/null +++ b/contrib/ipfilter/test/expected/ni13 @@ -0,0 +1,32 @@ +4500 0030 5e11 4000 8006 3961 c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 +4500 002c 0000 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 +4500 00c4 5e12 4000 8006 38cc c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00c4 0001 4000 4006 d6dd c0a8 7103 c0a8 7101 06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00d0 5e13 4000 8006 38bf c0a8 7101 c0a8 7103 05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0048 0002 4000 4006 d758 c0a8 7103 c0a8 7101 06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 +4500 0040 5e14 4000 8006 394e c0a8 7101 c0a8 7103 05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff +4500 0039 5e15 0000 802f 792b c0a8 7101 c0a8 7103 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 +4500 0020 0003 0000 ff2f 5856 c0a8 7103 c0a8 7101 2081 880b 0000 4000 ffff ffff +4500 0028 0004 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 +4500 0038 0005 0000 ff2f 583c c0a8 7103 c0a8 7101 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 002f 0006 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 +4500 003c 5e16 0000 802f 7927 c0a8 7101 c0a8 7103 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 0036 5e17 0000 802f 792c c0a8 7101 c0a8 7103 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 003a 0007 0000 ff2f 5838 c0a8 7103 c0a8 7101 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 0032 0008 0000 ff2f 583f c0a8 7103 c0a8 7101 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 +4500 0040 5e18 4000 8006 394a c0a8 7101 c0a8 7103 05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff +4500 0038 5e19 0000 802f 7928 c0a8 7101 c0a8 7103 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 0009 0000 ff2f 5832 c0a8 7103 c0a8 7101 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 5e1a 0000 802f 7921 c0a8 7101 c0a8 7103 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0044 000a 0000 ff2f 582b c0a8 7103 c0a8 7101 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0030 5e1b 0000 802f 792e c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 +4500 002a 000b 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 +4500 002c 000c 0000 ff2f 5841 c0a8 7103 c0a8 7101 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 +4500 0048 5e1c 0000 802f 7915 c0a8 7101 c0a8 7103 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0042 000d 0000 ff2f 582a c0a8 7103 c0a8 7101 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0030 5e1d 0000 802f 792c c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 +4500 0030 000e 0000 ff2f 583b c0a8 7103 c0a8 7101 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 +4500 002a 5e1e 0000 802f 7933 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 +4500 0032 5e1f 0000 802f 792a c0a8 7101 c0a8 7103 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc +4500 002a 000f 0000 ff2f 5840 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni14 b/contrib/ipfilter/test/expected/ni14 new file mode 100644 index 000000000000..852132396b58 --- /dev/null +++ b/contrib/ipfilter/test/expected/ni14 @@ -0,0 +1,32 @@ +4500 0030 5e11 4000 8006 ec0b c0a8 7101 7f00 0001 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 d44b 0000 0204 05b4 0101 0402 +4500 002c 0000 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 +4500 00c4 5e12 4000 8006 eb76 c0a8 7101 7f00 0001 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 954b 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00c4 0001 4000 4006 d6dd c0a8 7103 c0a8 7101 06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00d0 5e13 4000 8006 eb69 c0a8 7101 7f00 0001 05e7 06bb abf0 4b42 a564 6977 5018 fa54 5eb2 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0048 0002 4000 4006 d758 c0a8 7103 c0a8 7101 06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 +4500 0040 5e14 4000 8006 ebf8 c0a8 7101 7f00 0001 05e7 06bb abf0 4bea a564 6997 5018 fa34 9abb 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff +4500 0039 5e15 0000 802f 2bd6 c0a8 7101 7f00 0001 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 +4500 0020 0003 0000 ff2f 5856 c0a8 7103 c0a8 7101 2081 880b 0000 4000 ffff ffff +4500 0028 0004 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 +4500 0038 0005 0000 ff2f 583c c0a8 7103 c0a8 7101 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 002f 0006 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 +4500 003c 5e16 0000 802f 2bd2 c0a8 7101 7f00 0001 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 0036 5e17 0000 802f 2bd7 c0a8 7101 7f00 0001 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 003a 0007 0000 ff2f 5838 c0a8 7103 c0a8 7101 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 0032 0008 0000 ff2f a594 c0a8 7103 c0a8 7101 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 +4500 0040 5e18 4000 8006 ebf4 c0a8 7101 7f00 0001 05e7 06bb abf0 4c02 a564 6997 5018 fa34 9aa3 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff +4500 0038 5e19 0000 802f 2bd3 c0a8 7101 7f00 0001 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 0009 0000 ff2f a587 c0a8 7103 c0a8 7101 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 5e1a 0000 802f 2bcc c0a8 7101 7f00 0001 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0044 000a 0000 ff2f a580 c0a8 7103 c0a8 7101 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0030 5e1b 0000 802f 2bd9 c0a8 7101 7f00 0001 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 +4500 002a 000b 0000 ff2f a599 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 +4500 002c 000c 0000 ff2f a596 c0a8 7103 c0a8 7101 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 +4500 0048 5e1c 0000 802f 2bc0 c0a8 7101 7f00 0001 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0042 000d 0000 ff2f a57f c0a8 7103 c0a8 7101 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0030 5e1d 0000 802f 2bd7 c0a8 7101 7f00 0001 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 +4500 0030 000e 0000 ff2f a590 c0a8 7103 c0a8 7101 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 +4500 002a 5e1e 0000 802f 2bdc c0a8 7101 7f00 0001 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 +4500 0032 5e1f 0000 802f 2bd3 c0a8 7101 7f00 0001 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc +4500 002a 000f 0000 ff2f a595 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni15 b/contrib/ipfilter/test/expected/ni15 new file mode 100644 index 000000000000..1c59de17d466 --- /dev/null +++ b/contrib/ipfilter/test/expected/ni15 @@ -0,0 +1,32 @@ +4500 0030 0000 4000 8006 9772 c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 +4500 00c4 0001 4000 8006 96dd c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 c0a8 7101 06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00d0 0002 4000 8006 96d0 c0a8 7101 c0a8 7103 05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0048 69a8 4000 4006 6db2 c0a8 7103 c0a8 7101 06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 +4500 0040 0003 4000 8006 975f c0a8 7101 c0a8 7103 05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff +4500 0039 0004 0000 802f d73c c0a8 7101 c0a8 7103 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 c0a8 7101 2081 880b 0000 4000 ffff ffff +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 c0a8 7101 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 c0a8 7101 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 +4500 003c 0005 0000 802f d738 c0a8 7101 c0a8 7103 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 0036 0006 0000 802f d73d c0a8 7101 c0a8 7103 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 c0a8 7101 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 c0a8 7101 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 +4500 0040 0007 4000 8006 975b c0a8 7101 c0a8 7103 05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff +4500 0038 0008 0000 802f d739 c0a8 7101 c0a8 7103 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 69af 0000 ff2f ee8b c0a8 7103 c0a8 7101 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 0009 0000 802f d732 c0a8 7101 c0a8 7103 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 c0a8 7101 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0030 000a 0000 802f d73f c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 c0a8 7101 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 +4500 0048 000b 0000 802f d726 c0a8 7101 c0a8 7103 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 c0a8 7101 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0030 000c 0000 802f d73d c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 c0a8 7101 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 +4500 002a 000d 0000 802f d742 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 +4500 0032 000e 0000 802f d739 c0a8 7101 c0a8 7103 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni16 b/contrib/ipfilter/test/expected/ni16 new file mode 100644 index 000000000000..c30b0d22bac4 --- /dev/null +++ b/contrib/ipfilter/test/expected/ni16 @@ -0,0 +1,32 @@ +4500 0030 0000 4000 8006 9772 c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 +4500 002c 69a6 4000 4006 9376 c0a8 7103 0a02 0202 06bb 05e7 a564 68da abf0 4aa6 6012 8000 c8ee 0000 0204 05b4 +4500 00c4 0001 4000 8006 96dd c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00c4 69a7 4000 4006 92dd c0a8 7103 0a02 0202 06bb 05e7 a564 68db abf0 4b42 5018 832c f475 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 00d0 0002 4000 8006 96d0 c0a8 7101 c0a8 7103 05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0048 69a8 4000 4006 9358 c0a8 7103 0a02 0202 06bb 05e7 a564 6977 abf0 4bea 5018 832c 5ca0 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 +4500 0040 0003 4000 8006 975f c0a8 7101 c0a8 7103 05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff +4500 0039 0004 0000 802f d73c c0a8 7101 c0a8 7103 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 +4500 0020 69a9 0000 ff2f 1456 c0a8 7103 0a02 0202 2081 880b 0000 4000 ffff ffff +4500 0028 69aa 4000 4006 9376 c0a8 7103 0a02 0202 06bb 05e7 a564 6997 abf0 4c02 5010 832c db67 0000 +4500 0038 69ab 0000 ff2f 143c c0a8 7103 0a02 0202 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 002f 69ac 0000 ff2f 1444 c0a8 7103 0a02 0202 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 +4500 003c 0005 0000 802f d738 c0a8 7101 c0a8 7103 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 +4500 0036 0006 0000 802f d73d c0a8 7101 c0a8 7103 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 003a 69ad 0000 ff2f 1438 c0a8 7103 0a02 0202 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 +4500 0032 69ae 0000 ff2f 143f c0a8 7103 0a02 0202 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 +4500 0040 0007 4000 8006 975b c0a8 7101 c0a8 7103 05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff +4500 0038 0008 0000 802f d739 c0a8 7101 c0a8 7103 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 69af 0000 ff2f 1432 c0a8 7103 0a02 0202 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 +4500 003e 0009 0000 802f d732 c0a8 7101 c0a8 7103 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0044 69b0 0000 ff2f 142b c0a8 7103 0a02 0202 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 +4500 0030 000a 0000 802f d73f c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 +4500 002a 69b1 0000 ff2f 1444 c0a8 7103 0a02 0202 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 +4500 002c 69b2 0000 ff2f 1441 c0a8 7103 0a02 0202 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 +4500 0048 000b 0000 802f d726 c0a8 7101 c0a8 7103 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0042 69b3 0000 ff2f 142a c0a8 7103 0a02 0202 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 +4500 0030 000c 0000 802f d73d c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 +4500 0030 69b4 0000 ff2f 143b c0a8 7103 0a02 0202 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 +4500 002a 000d 0000 802f d744 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 +4500 0032 000e 0000 802f d73b c0a8 7101 c0a8 7103 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc +4500 002a 69b5 0000 ff2f 1440 c0a8 7103 0a02 0202 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni2 b/contrib/ipfilter/test/expected/ni2 index bf05cf01a147..6aef39f7ce86 100644 --- a/contrib/ipfilter/test/expected/ni2 +++ b/contrib/ipfilter/test/expected/ni2 @@ -1,10 +1,10 @@ -4510 002c bd0d 4000 3e06 bbd1 0101 0101 c0a8 0133 9c40 0077 a664 2485 0000 0000 6002 4000 2ca8 0000 0204 05b4 -4500 002c ce83 4000 7e06 606b c0a8 0133 0a01 0201 0077 05f6 fbdf 1a21 a664 2486 6012 2238 c0a8 0000 0204 05b4 -4510 0028 bd0e 4000 3e06 bbd4 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a22 5010 4470 29e3 0000 -4500 005b cf83 4000 7e06 5f3c c0a8 0133 0a01 0201 0077 05f6 fbdf 1a22 a664 2486 5018 2238 ce2a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0a -4510 0028 bd18 4000 3e06 bbca 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5010 4470 29b0 0000 -4510 002e bd1e 4000 3e06 bbbe 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5018 4470 1c98 0000 0000 0000 0d0a -4500 0048 e383 4000 7e06 4b4f c0a8 0133 0a01 0201 0077 05f6 fbdf 1a55 a664 248c 5018 2232 d80a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3331 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -4500 0038 d71d 4000 4001 9fca 0101 0101 c0a8 0133 0304 444f 0000 05a0 4500 05dc e483 4000 7e06 4ebb c0a8 0133 0101 0101 0077 9c40 fbdf 1a75 +4510 002c 0000 4000 3e06 78df 0101 0101 c0a8 0133 9c40 0077 a664 2485 0000 0000 6002 4000 2ca8 0000 0204 05b4 +4500 002c ce83 4000 7e06 606b c0a8 0133 0a01 0201 0077 05f6 fbdf 1a21 a664 2486 6012 2238 c0a8 0000 0204 05b4 +4510 0028 0001 4000 3e06 78e2 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a22 5010 4470 29e3 0000 +4500 005b cf83 4000 7e06 5f3c c0a8 0133 0a01 0201 0077 05f6 fbdf 1a22 a664 2486 5018 2238 ce2a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0a +4510 0028 0002 4000 3e06 78e1 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5010 4470 29b0 0000 +4510 002e 0003 4000 3e06 78da 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5018 4470 1c98 0000 0000 0000 0d0a +4500 0048 e383 4000 7e06 4b4f c0a8 0133 0a01 0201 0077 05f6 fbdf 1a55 a664 248c 5018 2232 d80a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3331 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0038 0004 4000 4001 76e4 0101 0101 c0a8 0133 0304 444f 0000 05a0 4500 05dc e483 4000 7e06 4ebb c0a8 0133 0101 0101 0077 9c40 fbdf 1a75 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni3 b/contrib/ipfilter/test/expected/ni3 index cf535f378b3d..600b6249a3ec 100644 --- a/contrib/ipfilter/test/expected/ni3 +++ b/contrib/ipfilter/test/expected/ni3 @@ -1,4 +1,4 @@ -4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 -4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 003c 0000 4000 ff06 67a8 0606 0606 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 +4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni4 b/contrib/ipfilter/test/expected/ni4 index 95382cde5e90..cd5ebac85c75 100644 --- a/contrib/ipfilter/test/expected/ni4 +++ b/contrib/ipfilter/test/expected/ni4 @@ -1,4 +1,4 @@ -4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 -4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 003c 0000 4000 ff06 67a8 0606 0606 0404 0404 9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 +4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni5 b/contrib/ipfilter/test/expected/ni5 index 449c2c444c94..a64d8129820b 100644 --- a/contrib/ipfilter/test/expected/ni5 +++ b/contrib/ipfilter/test/expected/ni5 @@ -1,48 +1,47 @@ -4500 002c 10c9 4000 ff06 f232 0101 0101 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 f5a2 0000 0204 05b4 -4500 002c ffdd 4000 ef06 5374 96cb e002 c0a8 0103 0015 8032 3786 76c4 bd6b c9c9 6012 269c 8369 0000 0204 0584 -4500 0028 10ca 4000 ff06 f235 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 76c5 5010 269c 5aa0 0000 -4500 006f ffde 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 76c5 bd6b c9c9 5018 269c 967e 0000 3232 302d 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 7520 4e63 4654 5064 2053 6572 7665 7220 2866 7265 6520 6564 7563 6174 696f 6e61 6c20 6c69 6365 6e73 6529 2072 6561 6479 2e0d 0a -4500 0028 10cb 4000 ff06 f234 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 770c 5010 269c 5a59 0000 -ippr_ftp_server_valid:junk after cmd[220-Maintained by RSSS and RSPAS IT Staff (previously known as Coombs Comp] -4500 00c7 ffdf 4000 ef06 52d7 96cb e002 c0a8 0103 0015 8032 3786 770c bd6b c9c9 5018 269c 1087 0000 3232 302d 0d0a 3232 302d 4d61 696e 7461 696e 6564 2062 7920 5253 5353 2061 6e64 2052 5350 4153 2049 5420 5374 6166 6620 2870 7265 7669 6f75 736c 7920 6b6e 6f77 6e20 6173 2043 6f6f 6d62 7320 436f 6d70 7574 696e 6720 556e 6974 290d 0a32 3230 2d41 6e79 2070 726f 626c 656d 7320 636f 6e74 6163 7420 6674 706d 6173 7465 7240 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 750d 0a32 3230 2d0d 0a32 3230 200d 0a -4500 0028 10cc 4000 ff06 f233 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5010 269c 59ba 0000 -4500 0038 10cd 4000 ff06 f222 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5018 269c d1c5 0000 5553 4552 2061 6e6f 6e79 6d6f 7573 0d0a -4500 0028 ffe0 4000 ef06 5375 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5010 269c 9a00 0000 -4500 006c ffe1 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5018 269c b00f 0000 3333 3120 4775 6573 7420 6c6f 6769 6e20 6f6b 2c20 7365 6e64 2079 6f75 7220 636f 6d70 6c65 7465 2065 2d6d 6169 6c20 6164 6472 6573 7320 6173 2070 6173 7377 6f72 642e 0d0a -4500 0028 10ce 4000 ff06 f231 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5010 269c 5966 0000 -4500 0036 10cf 4000 ff06 f222 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5018 269c 373f 0000 5041 5353 2061 7661 6c6f 6e40 0d0a -4500 005f ffe2 4000 ef06 533c 96cb e002 c0a8 0103 0015 8032 3786 77ef bd6b c9e7 5018 269c 895e 0000 3233 302d 596f 7520 6172 6520 7573 6572 2023 3420 6f66 2035 3020 7369 6d75 6c74 616e 656f 7573 2075 7365 7273 2061 6c6c 6f77 6564 2e0d 0a -4500 0028 10d0 4000 ff06 f22f 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7826 5010 269c 5921 0000 -4500 0099 ffe3 4000 ef06 5301 96cb e002 c0a8 0103 0015 8032 3786 7826 bd6b c9e7 5018 269c d399 0000 3233 302d 0d0a 3233 302d 0d0a 3233 302d 4869 2e20 2057 6527 7265 2063 6c65 616e 696e 6720 7570 2e20 2041 6e79 2066 6565 6462 6163 6b20 6d6f 7374 2077 656c 636f 6d65 2e20 3130 2041 7567 2030 300d 0a32 3330 2d0d 0a32 3330 204c 6f67 6765 6420 696e 2061 6e6f 6e79 6d6f 7573 6c79 2e0d 0a -4500 0028 10d1 4000 ff06 f22e 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5010 269c 58b0 0000 -4500 0030 10d2 4000 ff06 f225 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5018 269c 86ae 0000 5459 5045 2049 0d0a -4500 0038 ffe4 4000 ef06 5361 96cb e002 c0a8 0103 0015 8032 3786 7897 bd6b c9ef 5018 269c 5fae 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a -4500 0028 10d3 4000 ff06 f22c 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5010 269c 5898 0000 -4500 003d 10d4 4000 ff06 f216 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5018 269c 4b67 0000 504f 5254 2031 2c31 2c31 2c31 2c31 3238 2c35 310d 0a -4500 0046 ffe5 4000 ef06 5352 96cb e002 c0a8 0103 0015 8032 3786 78a7 bd6b ca0c 5018 269c dbc3 0000 3230 3020 504f 5254 2063 6f6d 6d61 6e64 2073 7563 6365 7373 6675 6c2e 0d0a -4500 0030 10d5 4000 ff06 f222 0101 0101 96cb e002 8032 0015 bd6b ca04 3786 78c5 5018 269c 866b 0000 5459 5045 2041 0d0a -4500 0038 ffe6 4000 ef06 535f 96cb e002 c0a8 0103 0015 8032 3786 78c5 bd6b ca14 5018 269c 5f5b 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a -4500 002e 10d6 4000 ff06 f223 0101 0101 96cb e002 8032 0015 bd6b ca0c 3786 78d5 5018 269c a994 0000 4e4c 5354 0d0a -4500 002c ffe7 4000 ef06 536a 96cb e002 c0a8 0103 0014 8033 d9f8 11d4 0000 0000 6002 2238 d190 0000 0204 0584 -4500 002c 10d7 4000 ff06 327b c0a8 0103 96cb e002 8033 0014 bd78 5c12 d9f8 11d5 6012 02f8 d734 0000 0204 0584 -4500 0028 ffe8 4000 ef06 536d 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5010 269c cb1d 0000 -4500 005d ffe9 4000 ef06 5337 96cb e002 c0a8 0103 0015 8032 3786 78d5 bd6b ca1a 5018 269c eed0 0000 3135 3020 4f70 656e 696e 6720 4153 4349 4920 6d6f 6465 2064 6174 6120 636f 6e6e 6563 7469 6f6e 2066 6f72 202f 6269 6e2f 6c73 2e0d 0a -4500 0028 10d8 4000 ff06 327e c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 11d5 5010 6348 8e71 0000 -4500 0063 ffea 4000 ef06 5330 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5018 269c a315 0000 636f 6f6d 6273 7061 7065 7273 0d0a 6465 7074 730d 0a66 6f75 6e64 2d66 696c 6573 0d0a 696e 636f 6d69 6e67 0d0a 6e6c 632d 7465 7374 0d0a 7075 620d 0a -4500 0028 10d9 4000 ff06 327d c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1210 5010 6348 8e36 0000 -4500 0028 ffeb 4000 ef06 536a 96cb e002 c0a8 0103 0014 8033 d9f8 1210 bd78 5c13 5011 269c cae1 0000 -4500 0028 10da 4000 ff06 327c c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5010 6348 8e35 0000 -4500 0028 10db 4000 ff06 327b c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5011 6348 8e34 0000 -4500 0028 ffec 4000 ef06 5369 96cb e002 c0a8 0103 0014 8033 d9f8 1211 bd78 5c14 5010 269c cae0 0000 -4500 0028 10dc 4000 ff06 f223 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 790a 5010 269c 5812 0000 -4500 0040 ffed 4000 ef06 5350 96cb e002 c0a8 0103 0015 8032 3786 790a bd6b ca1a 5018 269c 7c9e 0000 3232 3620 4c69 7374 696e 6720 636f 6d70 6c65 7465 642e 0d0a -4500 0030 10dd 4000 ff06 f21a 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 7922 5018 269c 85f8 0000 5459 5045 2049 0d0a -4500 0038 ffee 4000 ef06 5357 96cb e002 c0a8 0103 0015 8032 3786 7922 bd6b ca22 5018 269c 5ef0 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a -4500 0028 10de 4000 ff06 f221 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5010 269c 57e2 0000 -4500 002e 10df 4000 ff06 f21a 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5018 269c b020 0000 5155 4954 0d0a -4500 0036 ffef 4000 ef06 5358 96cb e002 c0a8 0103 0015 8032 3786 7932 bd6b ca28 5018 269c a93c 0000 3232 3120 476f 6f64 6279 652e 0d0a -4500 0028 10e0 4000 ff06 f21f 0101 0101 96cb e002 8032 0015 bd6b ca20 3786 7940 5011 269c 57cd 0000 -4500 0028 fff0 4000 ef06 5365 96cb e002 c0a8 0103 0015 8032 3786 7940 bd6b ca28 5011 269c 981b 0000 -4500 0028 10e1 4000 ff06 3275 c0a8 0103 96cb e002 8032 0015 bd6b ca25 3786 7941 5010 269c 981e 0000 -4500 0028 fff1 4000 ef06 5364 96cb e002 c0a8 0103 0015 8032 3786 7941 bd6b ca29 5010 269c 981a 0000 +4500 002c 0000 4000 ff06 02fc 0101 0101 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 f5a2 0000 0204 05b4 +4500 002c ffdd 4000 ef06 5374 96cb e002 c0a8 0103 0015 8032 3786 76c4 bd6b c9c9 6012 269c 8369 0000 0204 0584 +4500 0028 0001 4000 ff06 02ff 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 76c5 5010 269c 5aa0 0000 +4500 006f ffde 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 76c5 bd6b c9c9 5018 269c 967e 0000 3232 302d 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 7520 4e63 4654 5064 2053 6572 7665 7220 2866 7265 6520 6564 7563 6174 696f 6e61 6c20 6c69 6365 6e73 6529 2072 6561 6479 2e0d 0a +4500 0028 0002 4000 ff06 02fe 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 770c 5010 269c 5a59 0000 +4500 00c7 ffdf 4000 ef06 52d7 96cb e002 c0a8 0103 0015 8032 3786 770c bd6b c9c9 5018 269c 1087 0000 3232 302d 0d0a 3232 302d 4d61 696e 7461 696e 6564 2062 7920 5253 5353 2061 6e64 2052 5350 4153 2049 5420 5374 6166 6620 2870 7265 7669 6f75 736c 7920 6b6e 6f77 6e20 6173 2043 6f6f 6d62 7320 436f 6d70 7574 696e 6720 556e 6974 290d 0a32 3230 2d41 6e79 2070 726f 626c 656d 7320 636f 6e74 6163 7420 6674 706d 6173 7465 7240 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 750d 0a32 3230 2d0d 0a32 3230 200d 0a +4500 0028 0003 4000 ff06 02fd 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5010 269c 59ba 0000 +4500 0038 0004 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5018 269c d1c5 0000 5553 4552 2061 6e6f 6e79 6d6f 7573 0d0a +4500 0028 ffe0 4000 ef06 5375 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5010 269c 9a00 0000 +4500 006c ffe1 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5018 269c b00f 0000 3333 3120 4775 6573 7420 6c6f 6769 6e20 6f6b 2c20 7365 6e64 2079 6f75 7220 636f 6d70 6c65 7465 2065 2d6d 6169 6c20 6164 6472 6573 7320 6173 2070 6173 7377 6f72 642e 0d0a +4500 0028 0005 4000 ff06 02fb 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5010 269c 5966 0000 +4500 0036 0006 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5018 269c 373f 0000 5041 5353 2061 7661 6c6f 6e40 0d0a +4500 005f ffe2 4000 ef06 533c 96cb e002 c0a8 0103 0015 8032 3786 77ef bd6b c9e7 5018 269c 895e 0000 3233 302d 596f 7520 6172 6520 7573 6572 2023 3420 6f66 2035 3020 7369 6d75 6c74 616e 656f 7573 2075 7365 7273 2061 6c6c 6f77 6564 2e0d 0a +4500 0028 0007 4000 ff06 02f9 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7826 5010 269c 5921 0000 +4500 0099 ffe3 4000 ef06 5301 96cb e002 c0a8 0103 0015 8032 3786 7826 bd6b c9e7 5018 269c d399 0000 3233 302d 0d0a 3233 302d 0d0a 3233 302d 4869 2e20 2057 6527 7265 2063 6c65 616e 696e 6720 7570 2e20 2041 6e79 2066 6565 6462 6163 6b20 6d6f 7374 2077 656c 636f 6d65 2e20 3130 2041 7567 2030 300d 0a32 3330 2d0d 0a32 3330 204c 6f67 6765 6420 696e 2061 6e6f 6e79 6d6f 7573 6c79 2e0d 0a +4500 0028 0008 4000 ff06 02f8 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5010 269c 58b0 0000 +4500 0030 0009 4000 ff06 02ef 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5018 269c 86ae 0000 5459 5045 2049 0d0a +4500 0038 ffe4 4000 ef06 5361 96cb e002 c0a8 0103 0015 8032 3786 7897 bd6b c9ef 5018 269c 5fae 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a +4500 0028 000a 4000 ff06 02f6 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5010 269c 5898 0000 +4500 003d 000b 4000 ff06 02e0 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5018 269c 4b67 0000 504f 5254 2031 2c31 2c31 2c31 2c31 3238 2c35 310d 0a +4500 0046 ffe5 4000 ef06 5352 96cb e002 c0a8 0103 0015 8032 3786 78a7 bd6b ca0c 5018 269c dbc3 0000 3230 3020 504f 5254 2063 6f6d 6d61 6e64 2073 7563 6365 7373 6675 6c2e 0d0a +4500 0030 000c 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b ca04 3786 78c5 5018 269c 866b 0000 5459 5045 2041 0d0a +4500 0038 ffe6 4000 ef06 535f 96cb e002 c0a8 0103 0015 8032 3786 78c5 bd6b ca14 5018 269c 5f5b 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a +4500 002e 000d 4000 ff06 02ed 0101 0101 96cb e002 8032 0015 bd6b ca0c 3786 78d5 5018 269c a994 0000 4e4c 5354 0d0a +4500 002c ffe7 4000 ef06 536a 96cb e002 c0a8 0103 0014 8033 d9f8 11d4 0000 0000 6002 2238 d190 0000 0204 0584 +4500 002c 000e 4000 ff06 02ee 0101 0101 96cb e002 8033 0014 bd78 5c12 d9f8 11d5 6012 02f8 96de 0000 0204 0584 +4500 0028 ffe8 4000 ef06 536d 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5010 269c cb1d 0000 +4500 005d ffe9 4000 ef06 5337 96cb e002 c0a8 0103 0015 8032 3786 78d5 bd6b ca1a 5018 269c eed0 0000 3135 3020 4f70 656e 696e 6720 4153 4349 4920 6d6f 6465 2064 6174 6120 636f 6e6e 6563 7469 6f6e 2066 6f72 202f 6269 6e2f 6c73 2e0d 0a +4500 0028 000f 4000 ff06 02f1 0101 0101 96cb e002 8033 0014 bd78 5c13 d9f8 11d5 5010 6348 4e1b 0000 +4500 0063 ffea 4000 ef06 5330 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5018 269c a315 0000 636f 6f6d 6273 7061 7065 7273 0d0a 6465 7074 730d 0a66 6f75 6e64 2d66 696c 6573 0d0a 696e 636f 6d69 6e67 0d0a 6e6c 632d 7465 7374 0d0a 7075 620d 0a +4500 0028 0010 4000 ff06 02f0 0101 0101 96cb e002 8033 0014 bd78 5c13 d9f8 1210 5010 6348 4de0 0000 +4500 0028 ffeb 4000 ef06 536a 96cb e002 c0a8 0103 0014 8033 d9f8 1210 bd78 5c13 5011 269c cae1 0000 +4500 0028 10da 4000 ff06 327c c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5010 6348 8e35 0000 +4500 0028 10db 4000 ff06 327b c0a8 0103 96cb e002 8033 0014 bd78 5c13 d9f8 1211 5011 6348 8e34 0000 +4500 0028 ffec 4000 ef06 5369 96cb e002 c0a8 0103 0014 8033 d9f8 1211 bd78 5c14 5010 269c cae0 0000 +4500 0028 0011 4000 ff06 02ef 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 790a 5010 269c 5812 0000 +4500 0040 ffed 4000 ef06 5350 96cb e002 c0a8 0103 0015 8032 3786 790a bd6b ca1a 5018 269c 7c9e 0000 3232 3620 4c69 7374 696e 6720 636f 6d70 6c65 7465 642e 0d0a +4500 0030 0012 4000 ff06 02e6 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 7922 5018 269c 85f8 0000 5459 5045 2049 0d0a +4500 0038 ffee 4000 ef06 5357 96cb e002 c0a8 0103 0015 8032 3786 7922 bd6b ca22 5018 269c 5ef0 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a +4500 0028 0013 4000 ff06 02ed 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5010 269c 57e2 0000 +4500 002e 0014 4000 ff06 02e6 0101 0101 96cb e002 8032 0015 bd6b ca1a 3786 7932 5018 269c b020 0000 5155 4954 0d0a +4500 0036 ffef 4000 ef06 5358 96cb e002 c0a8 0103 0015 8032 3786 7932 bd6b ca28 5018 269c a93c 0000 3232 3120 476f 6f64 6279 652e 0d0a +4500 0028 0015 4000 ff06 02eb 0101 0101 96cb e002 8032 0015 bd6b ca20 3786 7940 5011 269c 57cd 0000 +4500 0028 fff0 4000 ef06 5365 96cb e002 c0a8 0103 0015 8032 3786 7940 bd6b ca28 5011 269c 981b 0000 +4500 0028 10e1 4000 ff06 3275 c0a8 0103 96cb e002 8032 0015 bd6b ca25 3786 7941 5010 269c 981e 0000 +4500 0028 fff1 4000 ef06 5364 96cb e002 c0a8 0103 0015 8032 3786 7941 bd6b ca29 5010 269c 981a 0000 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni6 b/contrib/ipfilter/test/expected/ni6 new file mode 100644 index 000000000000..a4e4acebf537 --- /dev/null +++ b/contrib/ipfilter/test/expected/ni6 @@ -0,0 +1,9 @@ +4500 0054 cd8a 4000 ff11 1fbb c0a8 0601 c0a8 0701 8075 006f 0040 d26e 3e1d d249 0000 0000 0000 0002 0001 86a0 0000 0002 0000 0003 0000 0000 0000 0000 0000 0000 0000 0000 0001 86a3 0000 0003 0000 0011 0000 0000 +4500 0054 0000 4000 ff11 ec44 c0a8 0702 c0a8 0701 8075 006f 0040 d16d 3e1d d249 0000 0000 0000 0002 0001 86a0 0000 0002 0000 0003 0000 0000 0000 0000 0000 0000 0000 0000 0001 86a3 0000 0003 0000 0011 0000 0000 +4500 0038 cd83 4000 ff11 1fde c0a8 0701 c0a8 0601 006f 8075 0024 d805 3e1d d249 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0801 +4500 0038 0001 4000 ff11 ee5f c0a8 0602 c0a8 0601 006f 8075 0024 d904 3e1d d249 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0801 +4500 0044 d5a6 4000 ff11 17af c0a8 0601 c0a8 0701 80df 0801 0030 03f1 3e10 1fb1 0000 0000 0000 0002 0001 86a3 0000 0002 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0044 0002 4000 ff11 ec52 c0a8 0702 c0a8 0701 80df 0801 0030 02f0 3e10 1fb1 0000 0000 0000 0002 0001 86a3 0000 0002 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0034 0000 4000 fe11 ee65 c0a8 0701 c0a8 0601 0801 80df 0020 8ab8 3e10 1fb1 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 +4500 0034 0003 4000 fe11 ef61 c0a8 0602 c0a8 0601 0801 80df 0020 0000 3e10 1fb1 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 +------------------------------- diff --git a/contrib/ipfilter/test/expected/ni7 b/contrib/ipfilter/test/expected/ni7 index d03ec5829189..f0d0010d20b8 100644 --- a/contrib/ipfilter/test/expected/ni7 +++ b/contrib/ipfilter/test/expected/ni7 @@ -1,3 +1,3 @@ -4500 0028 4706 4000 0111 1eac 0404 0404 0606 0606 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 -4500 0038 809a 0000 ff01 2f1f 0202 0202 0404 0404 0b00 f91c 0000 0000 4500 0028 4706 4000 0111 26b4 0404 0404 0202 0202 afc9 829e 0014 c966 +4500 0028 4706 4000 0111 1eac 0404 0404 0606 0606 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 +4500 0038 0000 0000 ff01 afb9 0202 0202 0404 0404 0b00 f91c 0000 0000 4500 0028 4706 4000 0111 26b4 0404 0404 0202 0202 afc9 829e 0014 c966 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni8 b/contrib/ipfilter/test/expected/ni8 index ebee8bc43d33..4741b18cfb80 100644 --- a/contrib/ipfilter/test/expected/ni8 +++ b/contrib/ipfilter/test/expected/ni8 @@ -1,5 +1,5 @@ -4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 271f 0a02 0202 0404 0404 0303 a7fb 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 -4500 0058 809a 0000 ff01 26ff 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 -4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fb 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 +4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 0002 0000 ff01 abb3 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 ------------------------------- diff --git a/contrib/ipfilter/test/expected/ni9 b/contrib/ipfilter/test/expected/ni9 new file mode 100644 index 000000000000..9effc52d3d2f --- /dev/null +++ b/contrib/ipfilter/test/expected/ni9 @@ -0,0 +1,5 @@ +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 0000 0000 ff01 adb7 0303 0303 0404 0404 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 +4500 0058 0001 0000 ff01 ad96 0303 0303 0404 0404 0303 0735 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 +4500 0038 0002 0000 ff01 abb3 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 +------------------------------- diff --git a/contrib/ipfilter/test/expected/p1 b/contrib/ipfilter/test/expected/p1 new file mode 100644 index 000000000000..c3f7afa66f55 --- /dev/null +++ b/contrib/ipfilter/test/expected/p1 @@ -0,0 +1,19 @@ +nomatch +pass +nomatch +nomatch +nomatch +pass +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: +List of active state sessions: +List of configured pools +table role = ipf type = tree number = 100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p2 b/contrib/ipfilter/test/expected/p2 new file mode 100644 index 000000000000..bb15bdf7b146 --- /dev/null +++ b/contrib/ipfilter/test/expected/p2 @@ -0,0 +1,20 @@ +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +pass +List of active MAP/Redirect filters: + +List of active sessions: +List of active state sessions: +List of configured pools +List of configured hash tables +# 'anonymous' table +table role = ipf type = hash number = 2147483649 size = 3 + { 4.4.0.0/16; 127.0.0.1/32; }; +List of groups configured (set 0) +List of groups configured (set 1) +------------------------------- diff --git a/contrib/ipfilter/test/expected/p3 b/contrib/ipfilter/test/expected/p3 new file mode 100644 index 000000000000..136543f82291 --- /dev/null +++ b/contrib/ipfilter/test/expected/p3 @@ -0,0 +1,33 @@ +pass +nomatch +nomatch +nomatch +nomatch +pass +block +nomatch +nomatch +pass +nomatch +block +List of active MAP/Redirect filters: + +List of active sessions: +List of active state sessions: +List of configured pools +List of configured hash tables +group-map out role = ipf number = 2010 size = 5 + { 5.0.0.0/8, group = 2040; 4.4.0.0/16, group = 2020; 2.2.2.2/32, group = 2020; }; +group-map in role = ipf number = 1010 size = 3 + { 3.3.0.0/16, group = 1030; 1.1.1.1/32, group = 1020; }; +List of groups configured (set 0) +Dev.0. Group 1020 Ref 1 Flags 0x8000 +2 pass in all group 1020 +Dev.0. Group 1030 Ref 1 Flags 0x8000 +2 block in all group 1030 +Dev.0. Group 2020 Ref 2 Flags 0x4000 +4 pass out all group 2020 +Dev.0. Group 2040 Ref 1 Flags 0x4000 +2 block out all group 2040 +List of groups configured (set 1) +------------------------------- diff --git a/contrib/ipfilter/test/hextest b/contrib/ipfilter/test/hextest index c500c6b5cc12..b7b0b2c75e42 100644 --- a/contrib/ipfilter/test/hextest +++ b/contrib/ipfilter/test/hextest @@ -13,7 +13,7 @@ fi echo "$1..."; /bin/cp /dev/null results/$1 ( while read rule; do - echo "$rule" | ../ipftest -br - -Hi input/$1 >> results/$1; + echo "$rule" | ../ipftest -br - -F hex -i input/$1 >> results/$1; if [ $? -ne 0 ] ; then exit 1; fi diff --git a/contrib/ipfilter/test/input/f11 b/contrib/ipfilter/test/input/f11 index 25c670d18332..c54bb80eb476 100644 --- a/contrib/ipfilter/test/input/f11 +++ b/contrib/ipfilter/test/input/f11 @@ -6,7 +6,7 @@ in on e0 tcp 1.1.1.1,1 2.1.2.2,23 A in on e0 tcp 1.1.1.1,1 2.1.2.2,25 A in on e1 tcp 2.1.2.2,23 1.1.1.1,1 A in on e1 tcp 2.1.2.2,25 1.1.1.1,1 A -in on e0 tcp 1.1.1.1,1 2.1.2.2,23 F +in on e0 tcp 1.1.1.1,1 2.1.2.2,23 FA in on e0 tcp 1.1.1.1,1 2.1.2.2,23 A in on e0 tcp 1.1.1.1,2 2.1.2.2,23 A in on e1 udp 1.1.1.1,1 4.4.4.4,53 diff --git a/contrib/ipfilter/test/input/f12 b/contrib/ipfilter/test/input/f12 index 682202f3ab4e..52edde110442 100644 --- a/contrib/ipfilter/test/input/f12 +++ b/contrib/ipfilter/test/input/f12 @@ -1,35 +1,44 @@ # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF SYN -45 00 0028 0000 4000 3f 06 36cd 01010101 02010101 -0401 0019 00000000 00000000 50 02 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 36cd 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5002 2000 86c5 0000 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF ACK -45 00 0028 0000 4000 3f 06 36cd 01010101 02010101 -0401 0019 00000000 00000000 50 10 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 36cd 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 ACK -45 00 0028 0000 6000 3f 06 16cd 01010101 02010101 -0401 0019 00000000 00000000 50 10 2000 0000 0000 +[] +4500 0028 0000 6000 3f06 16cd 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0 -45 00 001c 0000 6000 3f 06 16d9 01010101 02010101 -0401 0019 00000000 +[] +4500 001c 0000 6000 3f06 16d9 0101 0101 0201 0101 +0401 0019 0000 0000 # 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 ACK -45 00 001c 0000 6001 3f 06 16d8 01010101 02010101 -00000000 50 10 2000 +[] +4500 001c 0000 6001 3f06 16d8 0101 0101 0201 0101 +0000 0000 5010 2000 # 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0 -45 00 0014 0000 6000 3f 11 16d6 01010101 02010101 +[] +4500 0014 0000 6000 3f11 16d6 0101 0101 0201 0101 # 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 0018 0000 2000 3f 11 56d2 01010101 02010101 +[] +4500 0018 0000 2000 3f11 56d2 0101 0101 0201 0101 0035 0035 # 1.1.1.1,1 -> 2.1.1.1,1 TTL=63 UDP MF FO=0 -45 00 001c 0000 2000 3f 11 56ce 01010101 02010101 -0001 0001 0004 0000 +[] +4500 001c 0000 2000 3f11 56ce 0101 0101 0201 0101 +0001 0001 0004 fadc # 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 001c 0000 2000 3f 11 56ce 01010101 02010101 -0035 0035 0004 0000 +[] +4500 001c 0000 2000 3f11 56ce 0101 0101 0201 0101 +0035 0035 0004 fa74 diff --git a/contrib/ipfilter/test/input/f13 b/contrib/ipfilter/test/input/f13 index d1c04d8fab2e..0ca607ea17e1 100644 --- a/contrib/ipfilter/test/input/f13 +++ b/contrib/ipfilter/test/input/f13 @@ -1,51 +1,51 @@ # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF,MF,FO=0 SYN -45 00 0028 0001 4000 3f 06 36cc 01010101 02010101 -0401 0019 00000000 00000000 50 02 2000 0000 0000 +4500 0028 0001 4000 3f06 36cc 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 50 02 2000 86c5 0000 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP MF ACK -45 00 0024 0002 2000 3f 06 56cf 01010101 02010101 -0401001900000000 0000000050102000 +4500 0024 0002 2000 3f06 56cf 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP FO=2 ACK -45 00 002c 0002 0002 3f 06 76c5 01010101 02010101 -0000000000010203 0405060708090a0b 0c0d0e0f10111213 +4500 002c 0002 0002 3f06 76c5 0101 0101 0201 0101 +0000 0000 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 1213 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 SYN -45 00 0028 0003 6000 3f 06 16ca 01010101 02010101 -0401 0019 00000000 00000000 50 10 2000 0000 0000 +4500 0028 0003 6000 3f06 16ca 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 0000 0000 # 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0 -45 00 001c 0004 6000 3f 06 16d5 01010101 02010101 -0401 0019 00000000 +4500 001c 0004 6000 3f06 16d5 0101 0101 0201 0101 +0401 0019 0000 0000 # 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 SYN -45 00 001c 0005 6001 3f 06 16d3 01010101 02010101 -00000000 50 10 2000 +4500 001c 0005 6001 3f06 16d3 0101 0101 0201 0101 +0000 0000 5010 2000 # 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0 -45 00 0014 0006 6000 3f 11 16d0 01010101 02010101 +4500 0014 0006 6000 3f11 16d0 0101 0101 0201 0101 # 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 0018 0007 2000 3f 11 56cb 01010101 02010101 +4500 0018 0007 2000 3f11 56cb 0101 0101 0201 0101 0035 0035 # 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 001c 0008 2000 3f 11 56c6 01010101 02010101 -0035003500040000 +4500 001c 0008 2000 3f11 56c6 0101 0101 0201 0101 +0035 0035 0004 0000 # 1.1.1.1,53 -> 2.1.1.1,54 TTL=63 UDP MF FO=0 (short) -45 00 0018 0008 2000 3f 11 56ca 01010101 02010101 -00350036 +4500 0018 0008 2000 3f11 56ca 0101 0101 0201 0101 +0035 0036 # 1.1.1.1,21 -> 2.1.1.1,54 TTL=63 UDP MF FO=0 -45 00 001c 0008 2000 3f 11 56c6 01010101 02010101 -0015003600040000 +4500 001c 0008 2000 3f11 56c6 0101 0101 0201 0101 +0015 0036 0004 0000 # 1.1.1.1,21 -> 2.1.1.1,54 TTL=63 TCP MF FO=0 -45 00 001c 0008 2000 3f 06 56d1 01010101 02010101 -0015 0036 00000000 00000000 50 02 2000 0000 0000 +4500 001c 0008 2000 3f06 56d1 0101 0101 0201 0101 +0015 0036 0000 0000 0000 0000 50 02 2000 0000 0000 # 1.1.1.1 -> 2.1.1.1 TTL=63 UDP FO=1 -45 00 001c 0008 0001 3f 11 76c5 01010101 02010101 -0000000000000000 +4500 001c 0008 0001 3f11 76c5 0101 0101 0201 0101 +0000 0000 0000 0000 diff --git a/contrib/ipfilter/test/input/f17 b/contrib/ipfilter/test/input/f17 index 1eba7e7b838b..18af566af32e 100644 --- a/contrib/ipfilter/test/input/f17 +++ b/contrib/ipfilter/test/input/f17 @@ -1,61 +1,28 @@ -# (1.1.1.1,54076,seq=0xbfd08989) -> (2.2.2.2,25,seq=0) SYN [out,ppp0] 4500 003c 8262 0000 4006 f254 0101 0101 0202 0202 d33c 0019 bfd0 8989 0000 0000 a002 4000 cfcd 0000 0204 05b4 0103 0300 0101 080a 008e 17f7 0000 0000 -# (2.2.2.2,25,seq=0x40203436) -> (1.1.1.1,54076,seq=0xbfdfcbc9) ACK [in,ppp0] 4500 003c 8262 0000 1106 2155 0202 0202 0101 0101 0019 d33c 4020 3436 bfdf cbc9 5010 4000 694a 0000 0204 0584 0103 0300 0101 080a 008e 17f7 0000 0000 -# (1.1.1.1,54076,seq=0xbfd08989) -> (2.2.2.2,25,seq=0x0) SYN [out,ppp0] 4500 003c 8265 0000 4006 f251 0101 0101 0202 0202 d33c 0019 bfd0 8989 0000 0000 a002 4000 cfc2 0000 0204 05b4 0103 0300 0101 080a 008e 1802 0000 0000 -# (2.2.2.2,25,seq=0xed674d4e) -> (1.1.1.1,54076,seq=0xbfd0898a) SYN-ACK [in,ppp0] 4500 002c 7442 4000 2906 d784 0202 0202 0101 0101 0019 d33c ed67 4d4e bfd0 898a 6012 2118 19c2 0000 0204 0584 -# -# (2.2.2.2,25,seq=0xbfd0898a) -> (1.1.1.1,54076,seq=0xed674d4e) ACK [out,ppp0] 4500 002c 8262 0000 4006 f264 0101 0101 0202 0202 d33c 0019 bfd0 898a ed67 4d4e -5010 4000 6190 0000 0000 - -# (1.1.1.1,54076,seq=0xcfd08989) -> (2.2.2.2,25,seq=0x0) SYN -[out,ppp0] -4500 003c 8265 0000 4006 f251 0101 0101 -0202 0202 d33c 0019 cfd0 8989 0000 0000 -a002 4000 bfc2 0000 0204 05b4 0103 0300 -0101 080a 008e 1802 0000 0000 - -# (1.1.1.1,54076,seq=0xcfd08989) -> (2.2.2.2,25,seq=0x0) SYN -[out,ppp0] -4500 003c 8266 0000 4006 f250 0101 0101 -0202 0202 d33c 0019 cfd0 8989 0000 0000 -a002 4000 bfc2 0000 0204 05b4 0103 0300 -0101 080a 008e 1802 0000 0000 - -# (2.2.2.2,25,seq=0xed674d4e) -> (1.1.1.1,54076,seq=0xcfd0898a) SYN-ACK -[in,ppp0] -4500 002c 7442 4000 2906 d784 0202 0202 -0101 0101 0019 d33c ed67 4d4e cfd0 898a -6012 2118 09c2 0000 0204 0584 - -# -# (2.2.2.2,25,seq=0xcfd0898a) -> (1.1.1.1,54076,seq=0xed674d4e) ACK -[out,ppp0] -4500 002c 8262 0000 4006 f264 0101 0101 -0202 0202 d33c 0019 cfd0 898a ed67 4d4e -5010 4000 6190 0000 0000 +5010 4000 0ce0 0000 0000 diff --git a/contrib/ipfilter/test/input/ipv6.1 b/contrib/ipfilter/test/input/ipv6.1 index 1d7d54687bc2..39208103edde 100644 --- a/contrib/ipfilter/test/input/ipv6.1 +++ b/contrib/ipfilter/test/input/ipv6.1 @@ -3,7 +3,7 @@ ef00 1001 2002 0001 0000 0000 0000 0070 2001 1002 3333 0001 0000 0000 0000 0001 8083 829a 0018 -f427 +f4c1 0000 0344 0000 0004 f8f1 9d3c ddba 0e00 [in,gif0] 6000 0000 0048 3a40 diff --git a/contrib/ipfilter/test/input/l1 b/contrib/ipfilter/test/input/l1 index afda0db3971b..56d766aa07bf 100644 --- a/contrib/ipfilter/test/input/l1 +++ b/contrib/ipfilter/test/input/l1 @@ -1,52 +1,64 @@ # 1.1.1.1,1025 -> 2.2.2.2,25 TTL=63 TCP DF SYN -45 00 0028 0000 4000 3f 06 0000 01010101 02020202 -0401 0019 00000000 00000000 50 02 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0000 0000 0000 5002 2000 85c3 0000 #in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 A -45 00 0028 0000 4000 3f 06 0000 01010101 02020202 -0401 0019 00000000 00000000 50 10 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0000 0000 0000 5010 2000 85b5 0000 #in on e1 tcp 2.1.2.2,25 1.1.1.1,1025 AS -45 00 0028 0000 4000 3f 06 0000 02020202 01010101 -0019 0401 00000000 00000000 50 12 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 35cb 0202 0202 0101 0101 +0019 0401 0000 0000 0000 0000 5012 2000 85b3 0000 #in on e1 tcp 2.1.2.2,25 1.1.1.1,1025 A -[out,e1] 45 00 0028 0000 4000 3f 06 0000 02020202 01010101 -0019 0401 00000000 00000000 50 10 2000 0000 0000 +[out,e1] 4500 0028 0000 4000 3f06 35cb 0202 0202 0101 0101 +0019 0401 0000 0000 0000 0000 5010 2000 85b5 0000 #in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 F -45 00 0028 0000 4000 3f 06 0000 01010101 02020202 -0401 0019 00000000 00000000 50 01 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0000 0000 0000 5011 2000 85b4 0000 #in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 A -45 00 0028 0000 4000 3f 06 0000 01010101 02020202 -0401 0019 00000000 00000000 50 10 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0000 0000 0000 5010 2000 85b5 0000 #in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 A -45 00 0028 0000 4000 3f 06 0000 01010101 02020202 -0401 0019 00000000 00000000 50 10 2000 0000 0000 +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0000 0000 0000 5010 2000 85b5 0000 #in on e1 udp 1.1.1.1,1 4.4.4.4,53 -45 00 0028 0000 4000 3f 11 0000 01010101 04040404 +[] +4500 0028 0000 4000 3f11 31bc 0101 0101 0404 0404 +0001 0035 0000 d16f 0102 0304 0506 0708 090a 0b0d + +#in on e1 udp 2.2.2.2,2 4.4.4.4,53 +[] +4500 0028 0000 4000 3f11 2fba 0202 0202 0404 0404 0001 0035 0000 0000 0102 0304 0506 0708 090a 0b0d #in on e1 udp 2.2.2.2,2 4.4.4.4,53 -45 00 0028 0000 4000 3f 11 0000 02020202 04040404 -0001 0035 0000 0000 0102 0304 0506 0708 090a 0b0d - -#in on e1 udp 2.2.2.2,2 4.4.4.4,53 -45 00 0038 0000 4000 3f 11 0000 02020202 04040404 -0001 0035 0000 0000 0102 0304 0506 0708 090a 0b0d +[] +4500 0038 0000 4000 3f11 2faa 0202 0202 0404 0404 +0001 0035 0000 d47b 0102 0304 0506 0708 090a 0b0d 0e0f 4061 4263 4465 4667 4869 4a6b 4c6d #in on e0 ip 4.4.4.4,53 1.1.1.1,1 -45 00 0014 0000 4000 3f 00 0000 02020202 04040404 +[] +4500 0014 0000 4000 3f00 2fdf 0202 0202 0404 0404 #in on e0 udp 3.3.3.3,1023 1.1.1.1,2049 -45 00 001c 0000 4000 3f 11 0000 03030303 01010101 -03ff 0801 0000 0000 +[] +4500 001c 0000 4000 3f11 33ca 0303 0303 0101 0101 +03ff 0801 0000 ebde #in on e0 udp 1.1.1.1,2049 3.3.3.3,1023 -45 00 001c 0000 4000 3f 11 0000 01010101 03030303 +[] +4500 001c 0000 4000 3f11 33ca 0101 0101 0303 0303 0801 03ff 0000 0000 diff --git a/contrib/ipfilter/test/input/n1 b/contrib/ipfilter/test/input/n1 index a60739036f86..04b24ef01198 100644 --- a/contrib/ipfilter/test/input/n1 +++ b/contrib/ipfilter/test/input/n1 @@ -19,7 +19,10 @@ in on zx0 255 10.1.1.2 10.3.4.5 in on zx0 tcp 10.1.1.1,1025 10.3.4.5,1025 out on zx0 icmp 10.1.1.1 10.4.3.2 in on zx0 icmp 10.4.3.2 10.2.2.2 +in on zx0 icmp 10.4.3.2 10.3.4.1 +in on zx0 icmp 10.4.3.2 10.3.4.2 in on zx0 icmp 10.4.3.2 10.3.4.3 +in on zx0 icmp 10.4.3.2 10.3.4.4 in on zx0 icmp 10.4.3.2 10.3.4.5 out on zx0 34 10.1.1.2 10.4.3.2 in on zx0 34 10.4.3.2 10.3.4.4 diff --git a/contrib/ipfilter/test/input/n10 b/contrib/ipfilter/test/input/n10 new file mode 100644 index 000000000000..321ed0bf9443 --- /dev/null +++ b/contrib/ipfilter/test/input/n10 @@ -0,0 +1,6 @@ +# TCP SYN packet with an MSS option +[out,ppp0] +4500 002c 10c9 4000 ff06 3289 c0a8 0103 +96cb e002 8032 0015 bd6b c9c8 0000 0000 +6002 2238 35f9 0000 0204 05b4 + diff --git a/contrib/ipfilter/test/input/n11 b/contrib/ipfilter/test/input/n11 new file mode 100644 index 000000000000..8712674489ea --- /dev/null +++ b/contrib/ipfilter/test/input/n11 @@ -0,0 +1,16 @@ +out on zx0 255 10.1.1.0 10.1.1.2 +out on zx0 255 10.1.1.1 10.1.1.2 +out on zx0 255 10.1.1.2 10.1.1.1 +out on zx0 255 10.2.2.1 10.1.2.1 +out on zx0 255 10.2.2.2 10.1.2.1 +in on zx0 255 10.1.1.1 10.1.1.2 +in on zx0 255 10.1.1.2 10.1.1.1 +in on zx0 255 10.2.2.1 10.2.1.1 +in on zx0 255 10.2.2.2 10.2.1.1 +in on zx0 255 10.2.2.3 10.1.1.1 +in on zx0 255 10.2.3.4 10.2.2.2 +in on zx0 255 10.1.1.1 10.2.2.2 +in on zx0 255 10.1.1.2 10.2.2.2 +in on zx0 255 10.1.1.0 10.3.4.5 +in on zx0 255 10.1.1.1 10.3.4.5 +in on zx0 255 10.1.1.2 10.3.4.5 diff --git a/contrib/ipfilter/test/input/n12 b/contrib/ipfilter/test/input/n12 new file mode 100644 index 000000000000..fb4d76de4755 --- /dev/null +++ b/contrib/ipfilter/test/input/n12 @@ -0,0 +1,18 @@ +[out,le0=192.168.1.188] +4510 0040 2020 4000 4006 17e1 c0a8 7e53 +c0a8 0303 12c2 0017 4e33 298e 0000 0000 +b002 4000 07af 0000 0204 05b4 0101 0402 +0103 0300 0101 080a 0c72 549e 0000 0000 + +[in,le0] +4500 003c 00b0 4000 fe06 f5fb c0a8 0303 +c0a8 01bc 0017 2710 f674 e02c 4e33 298f +a012 2798 e317 0000 0101 080a 2c05 b797 +0c72 549e 0103 0300 0204 05b4 + +[out,le0] +4510 0034 493b 4000 4006 eed1 c0a8 7e53 +c0a8 0303 12c2 0017 4e33 298f f674 e02d +8010 4000 8e2a 0000 0101 080a 0c72 549e +2c05 b797 + diff --git a/contrib/ipfilter/test/input/n4 b/contrib/ipfilter/test/input/n4 index 52c2d88ff43e..1218ef9e9103 100644 --- a/contrib/ipfilter/test/input/n4 +++ b/contrib/ipfilter/test/input/n4 @@ -1,5 +1,10 @@ in on zx0 tcp 10.3.3.3,12345 10.1.1.1,23 +out on zx0 tcp 10.2.2.1,10023 10.3.3.3,12345 in on zx0 tcp 10.3.3.3,12345 10.1.1.1,53 -in on zx0 tcp 10.3.3.3,12345 10.1.0.0,23 +out on zx0 tcp 10.2.2.1,10053 10.3.3.3,12345 +in on zx0 tcp 10.3.3.3,12346 10.1.0.0,23 +out on zx0 tcp 10.2.2.1,10023 10.3.3.3,12346 in on zx0 udp 10.3.3.3,12345 10.1.1.0,53 +out on zx0 udp 10.2.2.1,10053 10.3.3.3,12345 in on zx0 tcp 10.3.3.3,12345 10.1.1.0,53 +out on zx0 tcp 10.2.2.1,53 10.3.3.3,12345 diff --git a/contrib/ipfilter/test/input/n8 b/contrib/ipfilter/test/input/n8 new file mode 100644 index 000000000000..1f5b2130ba28 --- /dev/null +++ b/contrib/ipfilter/test/input/n8 @@ -0,0 +1,30 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[out,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efdf 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] 4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 +0000 f7df 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efde 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] 4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 +0000 f7de 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/ipfilter/test/input/n9 b/contrib/ipfilter/test/input/n9 new file mode 100644 index 000000000000..c4aada8f2c70 --- /dev/null +++ b/contrib/ipfilter/test/input/n9 @@ -0,0 +1,30 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[in,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efdf 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] 4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 +0000 f7df 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] 4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efde 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] 4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 +0000 f7de 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/ipfilter/test/input/ni1 b/contrib/ipfilter/test/input/ni1 index dc2f05eba034..8f548d5efca2 100644 --- a/contrib/ipfilter/test/input/ni1 +++ b/contrib/ipfilter/test/input/ni1 @@ -8,12 +8,13 @@ [in,df0] 4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 0b00 5f7b 0000 0000 -4500 0028 4706 4000 0111 1eac 0606 0606 0404 0404 -afc9 829e 0014 6308 +4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 +afc9 829e 0014 6308 [in,df0] 4500 0044 809a 0000 ff01 290d 0303 0303 0606 0606 0b00 0939 0000 0000 -4500 0028 4706 4000 0111 1eac 0606 0606 0404 0404 -afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 +4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 +afc9 829e 0014 6308 +0402 0000 3be5 468d 000a cfc3 diff --git a/contrib/ipfilter/test/input/ni10 b/contrib/ipfilter/test/input/ni10 index 041326f576ef..48ac22570283 100644 --- a/contrib/ipfilter/test/input/ni10 +++ b/contrib/ipfilter/test/input/ni10 @@ -1,17 +1,21 @@ #v tos len id off ttl p sum src dst # ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet # going out) +# IP 4.4.4.4 2.2.2.2 TCP(20480,80) [in,df0] 45 00 00 3c 47 06 40 00 ff 06 28 aa 04 04 04 04 02 02 02 02 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d8 e2 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) [out,df0] 4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 0303 acab 0000 0000 4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 5000 0050 0000 0001 +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) # ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) [out,df0] 45 00 00 58 80 9a 00 00 ff 01 2c fd 03 03 03 03 04 04 04 04 03 03 11 3f 00 00 00 00 45 00 00 3c 47 06 40 00 ff 06 20 a2 04 04 04 04 06 06 06 06 50 00 00 50 00 00 00 01 00 00 00 00 a0 02 16 d0 d0 da 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) [out,df0] 4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 0303 acab 0000 0000 diff --git a/contrib/ipfilter/test/input/ni12 b/contrib/ipfilter/test/input/ni12 new file mode 100644 index 000000000000..788e6036c407 --- /dev/null +++ b/contrib/ipfilter/test/input/ni12 @@ -0,0 +1,24 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[in,df0] 45 00 00 3c 47 06 40 00 ff 06 20 aa 04 04 04 04 0a 02 02 02 50 00 05 00 00 00 00 01 00 00 00 00 a0 02 16 d0 cc 32 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 0735 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 +0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 + diff --git a/contrib/ipfilter/test/input/ni13 b/contrib/ipfilter/test/input/ni13 new file mode 100644 index 000000000000..56ddb792abd2 --- /dev/null +++ b/contrib/ipfilter/test/input/ni13 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[in,pcn1=192.168.113.3] +4500 0030 5e11 4000 8006 3961 c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 21a1 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[out,pcn1] +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +6012 8000 a348 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[in,pcn1] +4500 00c4 5e12 4000 8006 38cc c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[out,pcn1] +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +5018 832c cecf 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[in,pcn1] +4500 00d0 5e13 4000 8006 38bf c0a8 7101 +c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[out,pcn1] +4500 0048 69a8 4000 4006 6db2 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +5018 832c 36fa 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e14 4000 8006 394e c0a8 7101 +c0a8 7103 05e7 06bb abf0 4bea a564 6997 +5018 fa34 e810 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[in,pcn1] +4500 0039 5e15 0000 802f 792b c0a8 7101 +c0a8 7103 3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[out,pcn1] +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 +c0a8 7101 2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[out,pcn1] +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +5010 832c b5c1 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 +c0a8 7101 3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[out,pcn1] +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 003c 5e16 0000 802f 7927 c0a8 7101 +c0a8 7103 3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 0036 5e17 0000 802f 792c c0a8 7101 +c0a8 7103 3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 +c0a8 7101 3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[out,pcn1] +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 +c0a8 7101 3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e18 4000 8006 394a c0a8 7101 +c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[in,pcn1] +4500 0038 5e19 0000 802f 7928 c0a8 7101 +c0a8 7103 3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[out,pcn1] +4500 003e 69af 0000 ff2f ee8b c0a8 7103 +c0a8 7101 3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[in,pcn1] +4500 003e 5e1a 0000 802f 7921 c0a8 7101 +c0a8 7103 3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[out,pcn1] +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 +c0a8 7101 3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[in,pcn1] +4500 0030 5e1b 0000 802f 792e c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[out,pcn1] +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[out,pcn1] +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 +c0a8 7101 3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0048 5e1c 0000 802f 7915 c0a8 7101 +c0a8 7103 3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 +c0a8 7101 3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[in,pcn1] +4500 0030 5e1d 0000 802f 792c c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[out,pcn1] +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 +c0a8 7101 3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[in,pcn1] +4500 002a 5e1e 0000 802f 7933 c0a8 7101 +c0a8 7103 3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 0000 0000 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[in,pcn1] +4500 0032 5e1f 0000 802f 792a c0a8 7101 +c0a8 7103 3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[out,pcn1] +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/ipfilter/test/input/ni14 b/contrib/ipfilter/test/input/ni14 new file mode 100644 index 000000000000..00f02900952c --- /dev/null +++ b/contrib/ipfilter/test/input/ni14 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[in,pcn1=192.168.113.3] +4500 0030 5e11 4000 8006 3961 c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 21a1 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[out,pcn1] +4500 002c 69a6 4000 4006 207b 7f00 0001 +c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +6012 8000 55f3 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[in,pcn1] +4500 00c4 5e12 4000 8006 38cc c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[out,pcn1] +4500 00c4 69a7 4000 4006 1fe2 7f00 0001 +c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +5018 832c 817a 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[in,pcn1] +4500 00d0 5e13 4000 8006 38bf c0a8 7101 +c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[out,pcn1] +4500 0048 69a8 4000 4006 205d 7f00 0001 +c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +5018 832c e9a4 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e14 4000 8006 394e c0a8 7101 +c0a8 7103 05e7 06bb abf0 4bea a564 6997 +5018 fa34 e810 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[in,pcn1] +4500 0039 5e15 0000 802f 792b c0a8 7101 +c0a8 7103 3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[out,pcn1] +4500 0020 69a9 0000 ff2f a15a 7f00 0001 +c0a8 7101 2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[out,pcn1] +4500 0028 69aa 4000 4006 207b 7f00 0001 +c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +5010 832c 686c 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 0038 69ab 0000 ff2f a140 7f00 0001 +c0a8 7101 3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[out,pcn1] +4500 002f 69ac 0000 ff2f a148 7f00 0001 +c0a8 7101 3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 003c 5e16 0000 802f 7927 c0a8 7101 +c0a8 7103 3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 0036 5e17 0000 802f 792c c0a8 7101 +c0a8 7103 3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 003a 69ad 0000 ff2f a13c 7f00 0001 +c0a8 7101 3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[out,pcn1] +4500 0032 69ae 0000 ff2f ee98 7f00 0001 +c0a8 7101 3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e18 4000 8006 394a c0a8 7101 +c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[in,pcn1] +4500 0038 5e19 0000 802f 7928 c0a8 7101 +c0a8 7103 3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[out,pcn1] +4500 003e 69af 0000 ff2f ee8b 7f00 0001 +c0a8 7101 3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[in,pcn1] +4500 003e 5e1a 0000 802f 7921 c0a8 7101 +c0a8 7103 3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[out,pcn1] +4500 0044 69b0 0000 ff2f ee84 7f00 0001 +c0a8 7101 3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[in,pcn1] +4500 0030 5e1b 0000 802f 792e c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[out,pcn1] +4500 002a 69b1 0000 ff2f ee9d 7f00 0001 +c0a8 7101 3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[out,pcn1] +4500 002c 69b2 0000 ff2f ee9a 7f00 0001 +c0a8 7101 3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0048 5e1c 0000 802f 7915 c0a8 7101 +c0a8 7103 3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0042 69b3 0000 ff2f ee83 7f00 0001 +c0a8 7101 3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[in,pcn1] +4500 0030 5e1d 0000 802f 792c c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[out,pcn1] +4500 0030 69b4 0000 ff2f ee94 7f00 0001 +c0a8 7101 3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[in,pcn1] +4500 002a 5e1e 0000 802f 7931 c0a8 7101 +c0a8 7103 3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 0000 0000 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[in,pcn1] +4500 0032 5e1f 0000 802f 7928 c0a8 7101 +c0a8 7103 3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[out,pcn1] +4500 002a 69b5 0000 ff2f ee99 7f00 0001 +c0a8 7101 3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/ipfilter/test/input/ni15 b/contrib/ipfilter/test/input/ni15 new file mode 100644 index 000000000000..fb445bb93c6f --- /dev/null +++ b/contrib/ipfilter/test/input/ni15 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[out,pcn1=192.168.113.3] +4500 0030 5e11 4000 8006 3961 c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 21a1 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[in,pcn1] +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +6012 8000 a348 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[out,pcn1] +4500 00c4 5e12 4000 8006 38cc c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[in,pcn1] +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +5018 832c cecf 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[out,pcn1] +4500 00d0 5e13 4000 8006 38bf c0a8 7101 +c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[in,pcn1] +4500 0048 69a8 4000 4006 6db2 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +5018 832c 36fa 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e14 4000 8006 394e c0a8 7101 +c0a8 7103 05e7 06bb abf0 4bea a564 6997 +5018 fa34 e810 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[out,pcn1] +4500 0039 5e15 0000 802f 792b c0a8 7101 +c0a8 7103 3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[in,pcn1] +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 +c0a8 7101 2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[in,pcn1] +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +5010 832c b5c1 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 +c0a8 7101 3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[in,pcn1] +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 003c 5e16 0000 802f 7927 c0a8 7101 +c0a8 7103 3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 0036 5e17 0000 802f 792c c0a8 7101 +c0a8 7103 3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 +c0a8 7101 3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[in,pcn1] +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 +c0a8 7101 3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e18 4000 8006 394a c0a8 7101 +c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[out,pcn1] +4500 0038 5e19 0000 802f 7928 c0a8 7101 +c0a8 7103 3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[in,pcn1] +4500 003e 69af 0000 ff2f ee8b c0a8 7103 +c0a8 7101 3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[out,pcn1] +4500 003e 5e1a 0000 802f 7921 c0a8 7101 +c0a8 7103 3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[in,pcn1] +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 +c0a8 7101 3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[out,pcn1] +4500 0030 5e1b 0000 802f 792e c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[in,pcn1] +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[in,pcn1] +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 +c0a8 7101 3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0048 5e1c 0000 802f 7915 c0a8 7101 +c0a8 7103 3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 +c0a8 7101 3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[out,pcn1] +4500 0030 5e1d 0000 802f 792c c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[in,pcn1] +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 +c0a8 7101 3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[out,pcn1] +4500 002a 5e1e 0000 802f 7931 c0a8 7101 +c0a8 7103 3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 0000 0000 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[out,pcn1] +4500 0032 5e1f 0000 802f 7928 c0a8 7101 +c0a8 7103 3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[in,pcn1] +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/ipfilter/test/input/ni16 b/contrib/ipfilter/test/input/ni16 new file mode 100644 index 000000000000..b1cc521ac8f2 --- /dev/null +++ b/contrib/ipfilter/test/input/ni16 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[out,pcn1=192.168.113.1] +4500 0030 5e11 4000 8006 5f07 0a02 0202 +c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 4747 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[in,pcn1] +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +6012 8000 a348 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[out,pcn1] +4500 00c4 5e12 4000 8006 5e72 0a02 0202 +c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +5018 faf0 0847 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[in,pcn1] +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +5018 832c cecf 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[out,pcn1] +4500 00d0 5e13 4000 8006 5e65 0a02 0202 +c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +5018 fa54 d1ad 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[in,pcn1] +4500 0048 69a8 4000 4006 6db2 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +5018 832c 36fa 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e14 4000 8006 5ef4 0a02 0202 +c0a8 7103 05e7 06bb abf0 4bea a564 6997 +5018 fa34 0db7 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[out,pcn1] +4500 0039 5e15 0000 802f 9ed1 0a02 0202 +c0a8 7103 3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[in,pcn1] +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 +c0a8 7101 2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[in,pcn1] +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +5010 832c b5c1 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 +c0a8 7101 3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[in,pcn1] +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 003c 5e16 0000 802f 9ecd 0a02 0202 +c0a8 7103 3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 0036 5e17 0000 802f 9ed2 0a02 0202 +c0a8 7103 3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 +c0a8 7101 3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[in,pcn1] +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 +c0a8 7101 3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e18 4000 8006 5ef0 0a02 0202 +c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +5018 fa34 0d9f 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[out,pcn1] +4500 0038 5e19 0000 802f 9ece 0a02 0202 +c0a8 7103 3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[in,pcn1] +4500 003e 69af 0000 ff2f ee8b c0a8 7103 +c0a8 7101 3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[out,pcn1] +4500 003e 5e1a 0000 802f 9ec7 0a02 0202 +c0a8 7103 3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[in,pcn1] +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 +c0a8 7101 3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[out,pcn1] +4500 0030 5e1b 0000 802f 9ed4 0a02 0202 +c0a8 7103 3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[in,pcn1] +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[in,pcn1] +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 +c0a8 7101 3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0048 5e1c 0000 802f 9ebb 0a02 0202 +c0a8 7103 3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 +c0a8 7101 3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[out,pcn1] +4500 0030 5e1d 0000 802f 9ed2 0a02 0202 +c0a8 7103 3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[in,pcn1] +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 +c0a8 7101 3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[out,pcn1] +4500 002a 5e1e 0000 802f 9ed9 0a02 0202 +c0a8 7103 3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 0000 0000 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[out,pcn1] +4500 0032 5e1f 0000 802f 9ed0 0a02 0202 +c0a8 7103 3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[in,pcn1] +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/ipfilter/test/input/ni6 b/contrib/ipfilter/test/input/ni6 new file mode 100644 index 000000000000..70e80c0ce1d7 --- /dev/null +++ b/contrib/ipfilter/test/input/ni6 @@ -0,0 +1,54 @@ +[in,nf0] +4500 0054 cd8a 4000 ff11 20ba c0a8 0601 +c0a8 0602 8075 006f 0040 d36d 3e1d d249 +0000 0000 0000 0002 0001 86a0 0000 0002 +0000 0003 0000 0000 0000 0000 0000 0000 +0000 0000 0001 86a3 0000 0003 0000 0011 +0000 0000 + +[out,qfe0] +4500 0054 cd8a 4000 ff11 1fbb c0a8 0601 +c0a8 0701 8075 006f 0040 d26e 3e1d d249 +0000 0000 0000 0002 0001 86a0 0000 0002 +0000 0003 0000 0000 0000 0000 0000 0000 +0000 0000 0001 86a3 0000 0003 0000 0011 +0000 0000 + +[in,qfe0] +4500 0038 cd83 4000 ff11 1edd c0a8 0701 +c0a8 0702 006f 8075 0024 d704 3e1d d249 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0801 + +[out,nf0] +4500 0038 cd83 4000 ff11 1fde c0a8 0701 +c0a8 0601 006f 8075 0024 d805 3e1d d249 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0801 + +[in,nf0] +4500 0044 d5a6 4000 ff11 18ae c0a8 0601 +c0a8 0602 80df 0801 0030 04f0 3e10 1fb1 +0000 0000 0000 0002 0001 86a3 0000 0002 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +[out,qfe0] +4500 0044 d5a6 4000 ff11 17af c0a8 0601 +c0a8 0701 80df 0801 0030 03f1 3e10 1fb1 +0000 0000 0000 0002 0001 86a3 0000 0002 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +[in,qfe0] +4500 0034 0000 4000 fe11 ed64 c0a8 0701 +c0a8 0702 0801 80df 0020 89b7 3e10 1fb1 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 + +[out,nf0] +4500 0034 0000 4000 fe11 ee65 c0a8 0701 +c0a8 0601 0801 80df 0020 0000 3e10 1fb1 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 + diff --git a/contrib/ipfilter/test/input/ni7 b/contrib/ipfilter/test/input/ni7 index 954bb7bdc3cb..30f247d39ca9 100644 --- a/contrib/ipfilter/test/input/ni7 +++ b/contrib/ipfilter/test/input/ni7 @@ -7,7 +7,7 @@ [out,df0] 4500 0038 809a 0000 ff01 2d1d 0303 0303 -0404 0404 0b00 0125 0000 0000 -4500 0028 4706 4000 0111 1eac 0404 0404 0606 0606 +0404 0404 0b00 0125 0000 0000 4500 0028 +4706 4000 0111 1eac 0404 0404 0606 0606 afc9 829e 0014 c15e diff --git a/contrib/ipfilter/test/input/ni9 b/contrib/ipfilter/test/input/ni9 new file mode 100644 index 000000000000..788e6036c407 --- /dev/null +++ b/contrib/ipfilter/test/input/ni9 @@ -0,0 +1,24 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[in,df0] 45 00 00 3c 47 06 40 00 ff 06 20 aa 04 04 04 04 0a 02 02 02 50 00 05 00 00 00 00 01 00 00 00 00 a0 02 16 d0 cc 32 00 00 02 04 05 b4 04 02 08 0a 00 47 fb b0 00 00 00 00 01 03 03 00 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 0735 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 +0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 + diff --git a/contrib/ipfilter/test/input/p1 b/contrib/ipfilter/test/input/p1 new file mode 100644 index 000000000000..f6753fac4264 --- /dev/null +++ b/contrib/ipfilter/test/input/p1 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/ipfilter/test/input/p2 b/contrib/ipfilter/test/input/p2 new file mode 100644 index 000000000000..f6753fac4264 --- /dev/null +++ b/contrib/ipfilter/test/input/p2 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/ipfilter/test/input/p3 b/contrib/ipfilter/test/input/p3 new file mode 100644 index 000000000000..4a6666b7ec3a --- /dev/null +++ b/contrib/ipfilter/test/input/p3 @@ -0,0 +1,12 @@ +in 1.1.1.1 1.2.1.1 +in 1.2.1.1 1.1.1.1 +out 1.1.1.1 1.2.1.1 +out 1.2.1.1 1.1.1.1 +in 2.2.2.2 2.1.2.1 +out 2.1.2.1 2.2.2.2 +in 3.3.1.1 3.1.3.1 +out 3.1.3.1 3.3.1.1 +in 4.4.1.1 4.1.4.1 +out 4.1.4.1 4.4.1.1 +in 5.5.1.1 5.1.5.1 +out 5.1.5.1 5.5.1.1 diff --git a/contrib/ipfilter/test/intest b/contrib/ipfilter/test/intest index 98241fc0627b..e94ca0894e57 100755 --- a/contrib/ipfilter/test/intest +++ b/contrib/ipfilter/test/intest @@ -1,4 +1,5 @@ #!/bin/sh +mkdir -p results if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -12,7 +13,7 @@ else fi echo "$1..."; /bin/cp /dev/null results/$1 -../ipnat -nvf regress/$1 2>/dev/null > results/$1 +../ipnat -Rnvf regress/$1 2>/dev/null > results/$1 cmp expected/$1 results/$1 status=$? if [ $status = 0 ] ; then diff --git a/contrib/ipfilter/test/iptest b/contrib/ipfilter/test/iptest new file mode 100644 index 000000000000..bb3ab5ea86fc --- /dev/null +++ b/contrib/ipfilter/test/iptest @@ -0,0 +1,22 @@ +#!/bin/sh +mkdir -p results +if [ -f /usr/ucb/touch ] ; then + TOUCH=/usr/ucb/touch +else + if [ -f /usr/bin/touch ] ; then + TOUCH=/usr/bin/touch + else + if [ -f /bin/touch ] ; then + TOUCH=/bin/touch + fi + fi +fi +echo "$1..."; +/bin/cp /dev/null results/$1 +../ippool -f regress/$1 -nRv 2>/dev/null > results/$1 +cmp expected/$1 results/$1 +status=$? +if [ $status = 0 ] ; then + $TOUCH $1 +fi +exit $status diff --git a/contrib/ipfilter/test/itest b/contrib/ipfilter/test/itest index c1b5f573d543..333afde75f27 100644 --- a/contrib/ipfilter/test/itest +++ b/contrib/ipfilter/test/itest @@ -1,4 +1,5 @@ #!/bin/sh +mkdir -p results if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -12,7 +13,7 @@ else fi echo "$1..."; /bin/cp /dev/null results/$1 -../ipf -nvf regress/$1 2>/dev/null > results/$1 +../ipf -Rnvf regress/$1 2>/dev/null > results/$1 cmp expected/$1 results/$1 status=$? if [ $status = 0 ] ; then diff --git a/contrib/ipfilter/test/mhtest b/contrib/ipfilter/test/mhtest index 52a002754b14..a4d48d693476 100755 --- a/contrib/ipfilter/test/mhtest +++ b/contrib/ipfilter/test/mhtest @@ -16,7 +16,7 @@ echo "$1..."; /bin/cp /dev/null results/$1 -../ipftest -br regress/$1 -Hi input/$1 > results/$1 +../ipftest -br regress/$1 -F hex -i input/$1 > results/$1 if [ $? -ne 0 ] ; then exit 1 fi diff --git a/contrib/ipfilter/test/mtest b/contrib/ipfilter/test/mtest index b185abb2bf7f..2a3ed38b34f7 100755 --- a/contrib/ipfilter/test/mtest +++ b/contrib/ipfilter/test/mtest @@ -1,4 +1,6 @@ #!/bin/sh +format=$2 +mkdir -p results # multiple rules at the same time if [ -f /usr/ucb/touch ] ; then @@ -16,7 +18,7 @@ echo "$1..."; /bin/cp /dev/null results/$1 -../ipftest -br regress/$1 -i input/$1 > results/$1 +../ipftest -F $format -Rbr regress/$1 -i input/$1 > results/$1 if [ $? -ne 0 ] ; then exit 1 fi diff --git a/contrib/ipfilter/test/natipftest b/contrib/ipfilter/test/natipftest index 8627168ed2cd..f5cfdb8b2439 100755 --- a/contrib/ipfilter/test/natipftest +++ b/contrib/ipfilter/test/natipftest @@ -1,4 +1,15 @@ #!/bin/sh +mode=$1 +shift +if [ $3 = hex ] ; then + format="-xF $2" +else + format="-F $2" +fi +if [ "$4" != "" ] ; then + format="-T $4 $format" +fi +mkdir -p results if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -10,19 +21,39 @@ else fi fi fi -echo "$1..."; -/bin/cp /dev/null results/$1 -( while read rule; do - echo "$rule" | ../ipftest -bHx -r regress/$1.ipf -Nr - -i input/$1 >> \ - results/$1; + +case $mode in +single) + echo "$1..."; + /bin/cp /dev/null results/$1 + ( while read rule; do + echo "$rule" | ../ipftest -R $format -bx -r regress/$1.ipf -N - -i input/$1 >> \ + results/$1; + if [ $? -ne 0 ] ; then + exit 1; + fi + echo "-------------------------------" >> results/$1 + done ) < regress/$1.nat + cmp expected/$1 results/$1 + status=$? + if [ $status = 0 ] ; then + $TOUCH $1 + fi + ;; +multi) + echo "$1..."; + /bin/cp /dev/null results/$1 + ../ipftest -R $format -bx -r regress/$1.ipf -N regress/$1.nat \ + -i input/$1 >> results/$1; if [ $? -ne 0 ] ; then - exit 1; + exit 2; fi echo "-------------------------------" >> results/$1 -done ) < regress/$1.nat -cmp expected/$1 results/$1 -status=$? -if [ $status = 0 ] ; then - $TOUCH $1 -fi + cmp expected/$1 results/$1 + status=$? + if [ $status = 0 ] ; then + $TOUCH $1 + fi + ;; +esac exit $status diff --git a/contrib/ipfilter/test/nattest b/contrib/ipfilter/test/nattest index 2b3e931c41c4..78b757ec4341 100755 --- a/contrib/ipfilter/test/nattest +++ b/contrib/ipfilter/test/nattest @@ -1,4 +1,12 @@ #!/bin/sh +if [ $3 = hex ] ; then + format="-xF $2" +else + format="-F $2" +fi +if [ "$4" != "" ] ; then + format="-T $4 $format" +fi if [ -f /usr/ucb/touch ] ; then TOUCH=/usr/ucb/touch else @@ -13,7 +21,7 @@ fi echo "$1..."; /bin/cp /dev/null results/$1 ( while read rule; do - echo "$rule" | ../ipftest -Nbr - -i input/$1 >> results/$1; + echo "$rule" | ../ipftest $format -RbN - -i input/$1 >> results/$1; if [ $? -ne 0 ] ; then exit 1; fi diff --git a/contrib/ipfilter/test/ptest b/contrib/ipfilter/test/ptest new file mode 100644 index 000000000000..7deccd3354f4 --- /dev/null +++ b/contrib/ipfilter/test/ptest @@ -0,0 +1,31 @@ +#!/bin/sh +mkdir -p results +if [ -f /usr/ucb/touch ] ; then + TOUCH=/usr/ucb/touch +else + if [ -f /usr/bin/touch ] ; then + TOUCH=/usr/bin/touch + else + if [ -f /bin/touch ] ; then + TOUCH=/bin/touch + fi + fi +fi +echo "$1..."; +/bin/cp /dev/null results/$1 +if [ -f regress/$1.pool ] ; then + ../ipftest -RD -b -P regress/$1.pool -r regress/$1.ipf -i input/$1 >> \ + results/$1 +else + ../ipftest -RD -b -r regress/$1.ipf -i input/$1 >> results/$1 +fi +if [ $? -ne 0 ] ; then + exit 1; +fi +echo "-------------------------------" >> results/$1 +cmp expected/$1 results/$1 +status=$? +if [ $status = 0 ] ; then + $TOUCH $1 +fi +exit $status diff --git a/contrib/ipfilter/test/regress/bpf-f1 b/contrib/ipfilter/test/regress/bpf-f1 new file mode 100644 index 000000000000..2c8028311a7e --- /dev/null +++ b/contrib/ipfilter/test/regress/bpf-f1 @@ -0,0 +1,4 @@ +pass in bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass in bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } diff --git a/contrib/ipfilter/test/regress/bpf1 b/contrib/ipfilter/test/regress/bpf1 new file mode 100644 index 000000000000..2c8028311a7e --- /dev/null +++ b/contrib/ipfilter/test/regress/bpf1 @@ -0,0 +1,4 @@ +pass in bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass in bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } diff --git a/contrib/ipfilter/test/regress/i1 b/contrib/ipfilter/test/regress/i1 index 736801edcb2d..df60d2beb5b0 100644 --- a/contrib/ipfilter/test/regress/i1 +++ b/contrib/ipfilter/test/regress/i1 @@ -1,5 +1,6 @@ pass in all -block out all +block out \ +all log in all log body in all count in from any to any @@ -11,3 +12,5 @@ pass in log body quick from any to any block return-rst in quick on le0 proto tcp from any to any block return-icmp in on qe0 from any to any block return-icmp(1) in on qe0 from any to any +block return-icmp-as-dest(port-unr) in on qe0 from any to any +pass out on longNICname0 from test.host.dots to test\.host.dots diff --git a/contrib/ipfilter/test/regress/i11 b/contrib/ipfilter/test/regress/i11 index 68e92831b642..2999a8588b75 100644 --- a/contrib/ipfilter/test/regress/i11 +++ b/contrib/ipfilter/test/regress/i11 @@ -1,5 +1,8 @@ pass in on ed0 proto tcp from localhost to localhost port = telnet keep state block in log first on lo0 proto tcp/udp from any to any keep state -pass in proto udp from localhost to localhost port = 2049 keep frags +pass in proto udp from localhost to localhost port = 20499 keep frag pass in proto udp from localhost to localhost port = 53 keep state keep frags -pass in proto tcp from any port gt 1024 to localhost port eq 25 keep state +pass in on ed0 out-via vx0 proto udp from any to any keep state +pass out on ppp0 in-via le0 proto tcp from any to any keep state +pass in proto tcp from any port gt 1024 to localhost port eq 1024 keep state +pass in proto tcp all flags S keep state(strict,newisn,no-icmp-err,limit 101) diff --git a/contrib/ipfilter/test/regress/i12 b/contrib/ipfilter/test/regress/i12 index d923f08b2521..b8b2f3ea418e 100644 --- a/contrib/ipfilter/test/regress/i12 +++ b/contrib/ipfilter/test/regress/i12 @@ -1,4 +1,9 @@ -block in on eri0 all head 1 -pass in on eri0 proto icmp all group 1 -pass out on ed0 all head 1000000 -block out on ed0 proto udp all group 1000000 +pass in from 1.1.1.1/32 to 2.2.2.2/32 +pass in from (2.2.2.2/24,3.3.3.3/32) to 4.4.4.4/32 +pass in from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) +pass in from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (22,25) +pass in proto tcp from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (53,9) +pass in proto udp from (2.2.2.2/24,3.3.3.3/32) to (5.5.5.5/32,6.6.6.6/32) port = (53,9) +pass in from 10.10.10.10 to 11.11.11.11 +pass in from pool/101 to hash/202 +pass in from hash/303 to pool/404 diff --git a/contrib/ipfilter/test/regress/i13 b/contrib/ipfilter/test/regress/i13 new file mode 100644 index 000000000000..3ba343d1669b --- /dev/null +++ b/contrib/ipfilter/test/regress/i13 @@ -0,0 +1,8 @@ +a=any; +b="from $a"; +c='to $a'; +d=block; +e="pass in"; +$d in $b $c +f=" $b $c"; +$e${f} diff --git a/contrib/ipfilter/test/regress/i14 b/contrib/ipfilter/test/regress/i14 new file mode 100644 index 000000000000..3c9d7b81d283 --- /dev/null +++ b/contrib/ipfilter/test/regress/i14 @@ -0,0 +1,8 @@ +block in on eri0 all head 1 +pass in on eri0 proto icmp all group 1 +pass out on ed0 all head 1000000 +block out on ed0 proto udp all group 1000000 +block in on vm0 proto tcp/udp all head 101 +pass in from 1.1.1.1 to 2.2.2.2 group 101 +pass in proto tcp from 1.0.0.1 to 2.0.0.2 group 101 +pass in proto udp from 2.0.0.2 to 3.0.0.3 group 101 diff --git a/contrib/ipfilter/test/regress/i15 b/contrib/ipfilter/test/regress/i15 new file mode 100644 index 000000000000..5268ec3562b1 --- /dev/null +++ b/contrib/ipfilter/test/regress/i15 @@ -0,0 +1,5 @@ +pass out on fxp0 all set-tag(log=100) +pass out on fxp0 all set-tag(nat=foo) +pass out on fxp0 all set-tag(log=100, nat=200) +pass out on fxp0 all set-tag(log=2147483648, nat=overtherainbowisapotof) + diff --git a/contrib/ipfilter/test/regress/i2 b/contrib/ipfilter/test/regress/i2 index 101deaa30512..a3b9cd8ac522 100644 --- a/contrib/ipfilter/test/regress/i2 +++ b/contrib/ipfilter/test/regress/i2 @@ -1,6 +1,7 @@ log in proto tcp all pass in proto 6 from any to any pass in proto udp from localhost to localhost +block in proto ipv6 from any to any block in proto 17 from any to any block in proto 250 from any to any pass in proto tcp/udp from any to any diff --git a/contrib/ipfilter/test/regress/i3 b/contrib/ipfilter/test/regress/i3 index 15e98bfc71ff..0d82e8a0b834 100644 --- a/contrib/ipfilter/test/regress/i3 +++ b/contrib/ipfilter/test/regress/i3 @@ -1,5 +1,7 @@ log in all -pass in from 128.0.0.1/24 to 128.0.0.1/16 +pass in from 128.16/16 to 129.10.10/24 +pass in from 128.0.0.1/24 to 128\ +.0.0.1/16 pass in from 128.0.0.1/0xffffff00 to 128.0.0.1/0xffff0000 pass in from 128.0.0.1/255.255.255.0 to 128.0.0.1/255.255.0.0 pass in from 128.0.0.1 mask 0xffffff00 to 128.0.0.1 mask 0xffff0000 diff --git a/contrib/ipfilter/test/regress/i4 b/contrib/ipfilter/test/regress/i4 index 1095ed97c91a..7170dc266e09 100644 --- a/contrib/ipfilter/test/regress/i4 +++ b/contrib/ipfilter/test/regress/i4 @@ -2,6 +2,7 @@ log in proto tcp from any port > 0 to any log in proto tcp from any to any port > 0 pass in proto 6 from any port != 0 to any port 0 >< 65535 pass in proto 17 from localhost port > 32000 to localhost port < 29000 -block in proto udp from any port != ntp to any port < ntp +block in proto udp from any port != \ntp to any port < echo block in proto tcp from any port = smtp to any port > 25 pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3 +pass in log first quick proto tcp from any port > 1023 to any port = 1723 flags S keep state diff --git a/contrib/ipfilter/test/regress/i6 b/contrib/ipfilter/test/regress/i6 index a35633bfd411..1a5308920a24 100644 --- a/contrib/ipfilter/test/regress/i6 +++ b/contrib/ipfilter/test/regress/i6 @@ -1,4 +1,10 @@ pass in on lo0 fastroute from any to any +pass in on lo0 to qe0 from localhost to localhost +pass in on le0 to qe0:127.0.0.1 from localhost to localhost pass in on lo0 dup-to qe0 from localhost to localhost -pass in on qe0 dup-to qe0:127.0.0.1 from localhost to localhost +pass in on le0 dup-to qe0:127.0.0.1 from localhost to localhost +pass in on le0 to hme0:10.1.1.1 dup-to qe0:127.0.0.1 from localhost to localhost block in quick on qe0 to qe1 from any to any +block in quick to qe1 from any to any +pass out quick dup-to hme0 from any to any +pass in quick fastroute all diff --git a/contrib/ipfilter/test/regress/i9 b/contrib/ipfilter/test/regress/i9 index 327cff45651d..2b8fb103324a 100644 --- a/contrib/ipfilter/test/regress/i9 +++ b/contrib/ipfilter/test/regress/i9 @@ -1,5 +1,7 @@ -pass in from localhost to localhost with short +pass in from localhost to localhost with short,frags block in from any to any with ipopts pass in from any to any with opt nop,rr,zsu pass in from any to any with opt nop,rr,zsu not opt ssrr,lsrr pass in from localhost to localhost with not frag +pass in proto tcp all flags S with not oow keep state +pass in proto tcp all flags S with not bad,bad-src,bad-nat diff --git a/contrib/ipfilter/test/regress/in1 b/contrib/ipfilter/test/regress/in1 index 59c5754180a9..145e3d038861 100644 --- a/contrib/ipfilter/test/regress/in1 +++ b/contrib/ipfilter/test/regress/in1 @@ -23,3 +23,5 @@ map le0 0/0 -> 0/32 frag age 10 map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20 map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag age 30 map fxp0 from 192.168.0.0/18 to 0/0 port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp +map thisisalonginte 0/0 -> 0/32 mssclamp 1452 tag freddyliveshere +map bar0 0/0 -> 0/32 icmpidmap icmp 1000:2000 diff --git a/contrib/ipfilter/test/regress/in2 b/contrib/ipfilter/test/regress/in2 index 33151f0e85cd..222a28cfeca8 100644 --- a/contrib/ipfilter/test/regress/in2 +++ b/contrib/ipfilter/test/regress/in2 @@ -1,22 +1,67 @@ -rdr le0 0/0 port 0 -> 1.1.1.1 port 0 -rdr le0 0/0 port 0 -> 1.1.1.1 port 0 ip -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 ip -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 tcp -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 udp -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 tcp/udp -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 icmp -rdr le0 0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 tcp round-robin -rdr le0 0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin -rdr le0 0/0 port 0 -> 1.1.1.1 port 0 ip frag -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 icmp frag -rdr le0 0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 tcp round-robin frag -rdr le0 0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag -rdr le0 0/0 port 0 -> 1.1.1.1 port 0 ip frag age 10 -rdr le0 0/0 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 icmp frag age 10 -rdr le0 0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 -rdr le0 0/0 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 -rdr le0 0/0 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 tcp +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp/udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10 sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 sticky mssclamp 1000 tag nattagcacheline +rdr ge0 9.8.7.6/32 -> 1.1.1.1 proxy port 21 ftp/tcp +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555 tcp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port = 5555 tcp +rdr le0 0/0 -> test.host.dots +rdr le0 0/0 -> test.host.dots,test.host.dots diff --git a/contrib/ipfilter/test/regress/in5 b/contrib/ipfilter/test/regress/in5 new file mode 100644 index 000000000000..d0a115c8b327 --- /dev/null +++ b/contrib/ipfilter/test/regress/in5 @@ -0,0 +1,22 @@ +rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 tcp +rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 ip +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 ip +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 udp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp/udp +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 port 888 icmp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 port 0 ip frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 icmp frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 port 0 ip frag age 10 +rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 ip frag age 10/20 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 icmp frag age 10 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag age 20 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag age 30 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag age 40 diff --git a/contrib/ipfilter/test/regress/in6 b/contrib/ipfilter/test/regress/in6 new file mode 100644 index 000000000000..694879945f04 --- /dev/null +++ b/contrib/ipfilter/test/regress/in6 @@ -0,0 +1,3 @@ +map foo0 from any port = 1 to any port != 0 -> 0/32 udp +map foo0 from any port < 1 to any port > 0 -> 0/32 tcp +map foo0 from any port <= 1 to any port >= 0 -> 0/32 tcp/udp diff --git a/contrib/ipfilter/test/regress/ip1 b/contrib/ipfilter/test/regress/ip1 new file mode 100644 index 000000000000..c31ba251bf2e --- /dev/null +++ b/contrib/ipfilter/test/regress/ip1 @@ -0,0 +1,78 @@ +#:%s/ \(number = [0-9]*\) \(type = [a-z]*\)/ \2 \1/g + +table role = ipf type = tree number = 1 + {; }; +table role = ipf type = tree number = 100 + { 1.2.3.4/32; !2.2.0.0/16; 2.2.2.0/24; }; +table role = nat type = tree number = 110 + { 1.2.3.4/32; !2.2.0.0/16; 2.2.2.0/24; }; +table role = auth type = tree number = 120 + { 1.2.3.4/32; !2.2.0.0/16; 2.2.2.0/24; }; +table role = count type = tree number = 130 + { 1.2.3.4; !2.2.0.0/16; 2.2.2.0/24; }; + +table role = ipf type = hash number = 2 + {; }; +table role = ipf type = hash number = 200 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 210 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 220 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 230 + { 0/0; 4/32; 1.2.3.4/32; }; + +table role = ipf type = hash number = 240 seed = 101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 250 seed = 101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 260 seed = 101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 270 seed = 101 + { 0/0; 4/32; 1.2.3.4/32; }; + +table role = ipf type = hash number = 2000 size = 1001 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 2000 size = 1001 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 2000 size = 1001 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 2000 size = 1001 + { 0/0; 4/32; 1.2.3.4/32; }; + +table role = ipf type = hash number = 100 size = 1001 seed = 101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 100 size = 1001 seed = 101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 100 size = 1001 seed = 101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 100 size = 1001 seed = 101 + { 0/0; 4/32; 1.2.3.4/32; }; + +group-map in role = ipf number = 300 group = 303 + { 0/0; 5/32; 1.2.3.4/32; }; +group-map in role = nat number = 300 group = 303 + { 0/0; 6/32; 1.2.3.4/32; }; +group-map in role = auth number = 300 group = 303 + { 0/0; 7/32; 1.2.3.4/32; }; +group-map in role = count number = 300 group = 303 + { 0/0; 8/32; 1.2.3.4/32; }; + +group-map out role = ipf number = 400 group = 303 + { 0/0; 5/32; 1.2.3.4/32, group = 606; }; +group-map out role = nat number = 400 group = 303 + { 0/0; 6/32; 1.2.3.4/32, group = 606; }; +group-map out role = auth number = 400 group = 303 + { 0/0; 7/32; 1.2.3.4/32, group = 606; }; +group-map out role = count number = 400 group = 303 + { 0/0; 8/32; 1.2.3.4/32, group = 606; }; + +group-map in role = ipf number = 500 + { 0/0, group = 10; 5/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = nat number = 500 + { 0/0, group = 10; 6/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = auth number = 500 + { 0/0, group = 10; 7/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = count number = 500 + { 0/0, group = 10; 8/32, group = 800; 1.2.3.4/32, group = 606; }; + diff --git a/contrib/ipfilter/test/regress/n10 b/contrib/ipfilter/test/regress/n10 new file mode 100644 index 000000000000..0f4819217f7a --- /dev/null +++ b/contrib/ipfilter/test/regress/n10 @@ -0,0 +1,3 @@ +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 100 +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 1000 +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 10000 diff --git a/contrib/ipfilter/test/regress/n11 b/contrib/ipfilter/test/regress/n11 new file mode 100644 index 000000000000..8cdf7fcf4627 --- /dev/null +++ b/contrib/ipfilter/test/regress/n11 @@ -0,0 +1,3 @@ +bimap zx0 10.1.1.1/32 -> 1.6.7.8/32 +bimap zx0 10.1.1.0/24 -> 10.2.2.2/32 +bimap zx0 10.1.1.0/24 -> 10.3.4.5/24 diff --git a/contrib/ipfilter/test/regress/n12 b/contrib/ipfilter/test/regress/n12 new file mode 100644 index 000000000000..225675b241da --- /dev/null +++ b/contrib/ipfilter/test/regress/n12 @@ -0,0 +1 @@ +map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 diff --git a/contrib/ipfilter/test/regress/n4 b/contrib/ipfilter/test/regress/n4 index b066c7ac2c56..e7c03145e677 100644 --- a/contrib/ipfilter/test/regress/n4 +++ b/contrib/ipfilter/test/regress/n4 @@ -3,3 +3,4 @@ rdr zx0 10.1.1.0/24 port 23 -> 10.2.2.1 port 10023 tcp rdr zx0 0/0 port 23 -> 10.2.2.1 port 10023 tcp rdr zx0 10.1.1.0/24 port 53 -> 10.2.2.1 port 10053 udp rdr zx0 10.1.1.0/24 port 0 -> 10.2.2.1 port 0 tcp +rdr zx0 10.1.1.0/24 port 0 -> 10.2.2.1 port 0 ip diff --git a/contrib/ipfilter/test/regress/n7 b/contrib/ipfilter/test/regress/n7 index 4abde530a21d..be995c2fe030 100644 --- a/contrib/ipfilter/test/regress/n7 +++ b/contrib/ipfilter/test/regress/n7 @@ -1,2 +1,3 @@ rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1 port 10023 tcp +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1 port = 10023 tcp rdr zx0 10.1.1.0/24 port 80 -> 10.2.2.1,1.2.2.129 port 3128 tcp diff --git a/contrib/ipfilter/test/regress/n8 b/contrib/ipfilter/test/regress/n8 new file mode 100644 index 000000000000..bf0e94f73544 --- /dev/null +++ b/contrib/ipfilter/test/regress/n8 @@ -0,0 +1 @@ +map icmp0 2.2.2.0/24 -> 10.10.10.0/24 diff --git a/contrib/ipfilter/test/regress/n9 b/contrib/ipfilter/test/regress/n9 new file mode 100644 index 000000000000..81a7ccd8c815 --- /dev/null +++ b/contrib/ipfilter/test/regress/n9 @@ -0,0 +1 @@ +rdr icmp0 4.4.4.0/24 port 0 -> 10.10.10.1 port 0 ip diff --git a/contrib/ipfilter/test/regress/ni10.nat b/contrib/ipfilter/test/regress/ni10.nat index 5257818530f3..2a04ef7948d0 100644 --- a/contrib/ipfilter/test/regress/ni10.nat +++ b/contrib/ipfilter/test/regress/ni10.nat @@ -1 +1 @@ -rdr df0 2.2.2.2/32 port 0 -> 6.6.6.6 port 0 ip +rdr df0 2.2.2.2/32 -> 6.6.6.6 diff --git a/contrib/ipfilter/test/regress/ni11.nat b/contrib/ipfilter/test/regress/ni11.nat index 87e967344e0a..1d0018cb34fa 100644 --- a/contrib/ipfilter/test/regress/ni11.nat +++ b/contrib/ipfilter/test/regress/ni11.nat @@ -1 +1 @@ -rdr df0 10.0.0.0/8 port 1000-2000 -> 1.1.1.1 port 40000 tcp/udp +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port 40000 tcp/udp diff --git a/contrib/ipfilter/test/regress/ni12.ipf b/contrib/ipfilter/test/regress/ni12.ipf new file mode 100644 index 000000000000..4151b6e666eb --- /dev/null +++ b/contrib/ipfilter/test/regress/ni12.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass in proto udp from any to any keep state +pass in proto tcp from any to any flags S keep state diff --git a/contrib/ipfilter/test/regress/ni12.nat b/contrib/ipfilter/test/regress/ni12.nat new file mode 100644 index 000000000000..8c36bc8701a5 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni12.nat @@ -0,0 +1 @@ +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port = 40000 tcp/udp diff --git a/contrib/ipfilter/test/regress/ni13.ipf b/contrib/ipfilter/test/regress/ni13.ipf new file mode 100644 index 000000000000..04b6d137e504 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni13.ipf @@ -0,0 +1,3 @@ +pass in quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/ipfilter/test/regress/ni13.nat b/contrib/ipfilter/test/regress/ni13.nat new file mode 100644 index 000000000000..7a879d8cd85a --- /dev/null +++ b/contrib/ipfilter/test/regress/ni13.nat @@ -0,0 +1 @@ +rdr pcn1 192.168.113.3/32 port 1723 -> 0.0.0.0 port 1723 proxy pptp diff --git a/contrib/ipfilter/test/regress/ni14.ipf b/contrib/ipfilter/test/regress/ni14.ipf new file mode 100644 index 000000000000..04b6d137e504 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni14.ipf @@ -0,0 +1,3 @@ +pass in quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/ipfilter/test/regress/ni14.nat b/contrib/ipfilter/test/regress/ni14.nat new file mode 100644 index 000000000000..c546e99029de --- /dev/null +++ b/contrib/ipfilter/test/regress/ni14.nat @@ -0,0 +1 @@ +rdr pcn1 192.168.113.3/32 port 1723 -> 127.0.0.1 port 1723 proxy pptp diff --git a/contrib/ipfilter/test/regress/ni15.ipf b/contrib/ipfilter/test/regress/ni15.ipf new file mode 100644 index 000000000000..1b9a013f5299 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni15.ipf @@ -0,0 +1,3 @@ +pass out quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/ipfilter/test/regress/ni15.nat b/contrib/ipfilter/test/regress/ni15.nat new file mode 100644 index 000000000000..420c7b722673 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni15.nat @@ -0,0 +1 @@ +map pcn1 0/0 -> 0/0 proxy port 1723 pptp/tcp diff --git a/contrib/ipfilter/test/regress/ni16.ipf b/contrib/ipfilter/test/regress/ni16.ipf new file mode 100644 index 000000000000..1b9a013f5299 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni16.ipf @@ -0,0 +1,3 @@ +pass out quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/ipfilter/test/regress/ni16.nat b/contrib/ipfilter/test/regress/ni16.nat new file mode 100644 index 000000000000..5fad3cdb20b0 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni16.nat @@ -0,0 +1 @@ +map pcn1 10.2.2.2/32 -> 0/32 proxy port 1723 pptp/tcp diff --git a/contrib/ipfilter/test/regress/ni6.ipf b/contrib/ipfilter/test/regress/ni6.ipf new file mode 100644 index 000000000000..f5b83b29ff3a --- /dev/null +++ b/contrib/ipfilter/test/regress/ni6.ipf @@ -0,0 +1,9 @@ +block out log quick on qfe0 from 192.168.7.0/24 to any +block out log quick on nf0 from 192.168.6.0/24 to any +pass in quick on nf0 proto tcp from any to any port = 111 flags S keep state +pass in quick on nf0 proto udp from any to any port = 111 keep state +block return-rst in log quick on nf0 proto tcp from any to any +block in log quick on nf0 from 192.168.7.0/24 to any +block return-rst in log quick on qfe0 proto tcp from any to any +block in log quick on qfe0 from 192.168.6.0/24 to any + diff --git a/contrib/ipfilter/test/regress/ni6.nat b/contrib/ipfilter/test/regress/ni6.nat new file mode 100644 index 000000000000..00d57d07cb2c --- /dev/null +++ b/contrib/ipfilter/test/regress/ni6.nat @@ -0,0 +1,3 @@ +rdr nf0 192.168.6.2 port 111 -> 192.168.7.1 port 111 udp proxy rpcbu +rdr nf0 192.168.6.2 port 111 -> 192.168.7.1 port 111 tcp proxy rpcbt +map qfe0 192.168.6.0/24 -> 192.168.7.2/32 diff --git a/contrib/ipfilter/test/regress/ni7.nat b/contrib/ipfilter/test/regress/ni7.nat index 5257818530f3..2a04ef7948d0 100644 --- a/contrib/ipfilter/test/regress/ni7.nat +++ b/contrib/ipfilter/test/regress/ni7.nat @@ -1 +1 @@ -rdr df0 2.2.2.2/32 port 0 -> 6.6.6.6 port 0 ip +rdr df0 2.2.2.2/32 -> 6.6.6.6 diff --git a/contrib/ipfilter/test/regress/ni8.nat b/contrib/ipfilter/test/regress/ni8.nat index 87e967344e0a..1d0018cb34fa 100644 --- a/contrib/ipfilter/test/regress/ni8.nat +++ b/contrib/ipfilter/test/regress/ni8.nat @@ -1 +1 @@ -rdr df0 10.0.0.0/8 port 1000-2000 -> 1.1.1.1 port 40000 tcp/udp +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port 40000 tcp/udp diff --git a/contrib/ipfilter/test/regress/ni9.ipf b/contrib/ipfilter/test/regress/ni9.ipf new file mode 100644 index 000000000000..66662419934e --- /dev/null +++ b/contrib/ipfilter/test/regress/ni9.ipf @@ -0,0 +1 @@ +pass in quick proto tcp from any to any flags S/SAFR keep state diff --git a/contrib/ipfilter/test/regress/ni9.nat b/contrib/ipfilter/test/regress/ni9.nat new file mode 100644 index 000000000000..8c36bc8701a5 --- /dev/null +++ b/contrib/ipfilter/test/regress/ni9.nat @@ -0,0 +1 @@ +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port = 40000 tcp/udp diff --git a/contrib/ipfilter/test/regress/p1.ipf b/contrib/ipfilter/test/regress/p1.ipf new file mode 100644 index 000000000000..acaf639ac1fb --- /dev/null +++ b/contrib/ipfilter/test/regress/p1.ipf @@ -0,0 +1 @@ +pass in from pool/100 to any diff --git a/contrib/ipfilter/test/regress/p1.pool b/contrib/ipfilter/test/regress/p1.pool new file mode 100644 index 000000000000..14ae3a3d40dd --- /dev/null +++ b/contrib/ipfilter/test/regress/p1.pool @@ -0,0 +1,2 @@ +table role = ipf type = tree number = 100 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; }; diff --git a/contrib/ipfilter/test/regress/p2.ipf b/contrib/ipfilter/test/regress/p2.ipf new file mode 100644 index 000000000000..5b58647eab5b --- /dev/null +++ b/contrib/ipfilter/test/regress/p2.ipf @@ -0,0 +1 @@ +pass out from hash=(127.0.0.1,4.4.0.0/16) to any diff --git a/contrib/ipfilter/test/regress/p3.ipf b/contrib/ipfilter/test/regress/p3.ipf new file mode 100644 index 000000000000..aad7cb358b5c --- /dev/null +++ b/contrib/ipfilter/test/regress/p3.ipf @@ -0,0 +1,6 @@ +call now fr_srcgrpmap/1010 in all +call now fr_dstgrpmap/2010 out all +pass in all group 1020 +block in all group 1030 +pass out all group 2020 +block out all group 2040 diff --git a/contrib/ipfilter/test/regress/p3.pool b/contrib/ipfilter/test/regress/p3.pool new file mode 100644 index 000000000000..3fadd59d3e1c --- /dev/null +++ b/contrib/ipfilter/test/regress/p3.pool @@ -0,0 +1,4 @@ +group-map in role = ipf number = 1010 + { 1.1.1.1/32, group = 1020; 3.3.0.0/16, group = 1030; }; +group-map out role = ipf number = 2010 group = 2020 + { 2.2.2.2/32; 4.4.0.0/16; 5.0.0.0/8, group = 2040; }; diff --git a/contrib/ipfilter/test/test.format b/contrib/ipfilter/test/test.format new file mode 100644 index 000000000000..090c8a983d0a --- /dev/null +++ b/contrib/ipfilter/test/test.format @@ -0,0 +1,77 @@ +#test input-format output-format +bpf-f1 text text +bpf1 text text +f1 text text +f2 text text +f3 text text +f4 text text +f5 text text +f6 text text +f7 text text +f8 text text +f9 text text +f10 text text +f11 text text +f12 hex hex +f13 hex hex +f14 text text +f15 text text +f16 text text +f17 hex hex +i1 text text +i2 text text +i3 text text +i4 text text +i5 text text +i6 text text +i7 text text +i8 text text +i9 text text +i10 text text +i11 text text +i12 text text +i13 text text +i14 text text +i15 text text +in1 text text +in2 text text +in3 text text +in4 text text +in5 text text +in6 text text +ip1 text text +ipv6.1 hex hex +ipv6.2 hex hex +ipv6.3 hex hex +l1 hex hex +n1 text text +n2 text text +n3 text text +n4 text text +n5 text text +n6 text text +n7 text text +n8 hex hex fr_update_ipid=0 +n9 hex hex fr_update_ipid=0 +n10 hex hex fr_update_ipid=0 +n11 text text +n12 hex hex fr_update_ipid=0 +ni1 hex hex fr_update_ipid=1 +ni2 hex hex fr_update_ipid=1 +ni3 hex hex fr_update_ipid=1 +ni4 hex hex fr_update_ipid=1 +ni5 hex hex fr_update_ipid=1 +ni6 hex hex fr_update_ipid=1 +ni7 hex hex fr_update_ipid=1 +ni8 hex hex fr_update_ipid=1 +ni9 hex hex fr_update_ipid=1 +ni10 hex hex fr_update_ipid=1 +ni11 hex hex fr_update_ipid=1 +ni12 hex hex fr_update_ipid=1 +ni13 hex hex fr_update_ipid=1 +ni14 hex hex fr_update_ipid=1 +ni15 hex hex fr_update_ipid=1 +ni16 hex hex fr_update_ipid=1 +p1 text text +p2 text text +p3 text text diff --git a/contrib/ipfilter/test/vfycksum.pl b/contrib/ipfilter/test/vfycksum.pl index b6a20761d039..9cb47f651d6f 100755 --- a/contrib/ipfilter/test/vfycksum.pl +++ b/contrib/ipfilter/test/vfycksum.pl @@ -62,7 +62,7 @@ sub tcpcheck { local($base) = $_[0]; local($hl) = $bytes[$base] / 256; return if (($hl >> 4) != 4); - return if ($bytes[3] & 0x1fff); + return if ($bytes[$base + 3] & 0x1fff); $hl &= 0xf; $hl <<= 1; @@ -79,10 +79,27 @@ sub tcpcheck { local($thl) = $bytes[$base + $hl + 6] >> 8; $thl &= 0xf0; $thl >>= 2; - if (($bytes[$base + 1] > ($cnt - $base) * 2) || - (($cnt - $base) * 2 < $hl + 20) || - (($cnt - $base) * 2 < $hl + $thl)) { - print " TCP: missing data"; + + $x = $bytes[$base + 1]; + $y = ($cnt - $base) * 2; + $z = 0; + if ($bytes[$base + 1] > ($cnt - $base) * 2) { + print "[cnt=$cnt base=$base]"; + $x = $bytes[$base + 1]; + $y = ($cnt - $base) * 2; + $z = 1; + } elsif (($cnt - $base) * 2 < $hl + 20) { + $x = ($cnt - $base) * 2; + $y = $hl + 20; + $z = 2; + } elsif (($cnt - $base) * 2 < $hl + $thl) { + $x = ($cnt - $base) * 2; + $y = $hl + $thl; + $z = 3; + } + + if ($z) { + print " TCP: missing data($x $y $z)"; return; } @@ -95,7 +112,7 @@ sub tcpcheck { $bytes[$tcpat + 8] = $osum; printf " TCP: (%x) %x != %x", $hs, $osum, $hs2; } else { - print " TCP: ok"; + print " TCP: ok ($x $y)"; } } @@ -161,8 +178,15 @@ sub icmpcheck { local($len) = $bytes[$base + 1] - ($hl << 1); - if ($len > $cnt * 2) { - print "missing icmp data\n"; + if ($bytes[$base + 1] > ($cnt - $base) * 2) { + print " ICMP: missing data(1)"; + return; + } elsif ($bytes[$base + 1] < ($hl << 1) + 8) { + print " ICMP: missing data(2)"; + return; + } elsif (($cnt - $base) * 2 < ($hl << 1) + 8) { + print " ICMP: missing data(3)"; + return; } local($osum) = $bytes[$base + $hl + 1]; @@ -240,6 +264,7 @@ $b=$_; $y = hex $x; s/[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] *(.*)/$1/; $bytes[$cnt] = $y; +#print "bytes[$cnt] = $x\n"; $cnt++; } diff --git a/contrib/ipfilter/todo b/contrib/ipfilter/todo index 4c2adf1e9868..5b2c05905214 100644 --- a/contrib/ipfilter/todo +++ b/contrib/ipfilter/todo @@ -7,9 +7,14 @@ fastroute works GENERAL: -------- +* support redirection like "rdr tun0 0/32 port 80 ..." + * use fr_tcpstate() with NAT code for increased NAT usage security or even fr_checkstate() - suspect this is not possible. +* add another alias for for interfaces ? as well as + all IP#'s associated with the box ? + time permitting: * load balancing across interfaces @@ -17,21 +22,13 @@ time permitting: * record buffering for TCP/UDP * modular application proxying -available +-done * allow multiple ip addresses in a source route list for ipsend -* complete Linux port to implement all the IP Filter features -return-rst done, to/dup-to/fastroute remain - ip_forward() problems :-( -on hold until rewrite +* port IP Filter to Linux +Not in this century. -* add a flag to automate src spoofing -done - -* ipfsync() should change IP#'s in current mappings as well as what's - in rules. -done - * document bimap * document NAT rule order processing @@ -43,22 +40,23 @@ in progress XDDD. I agree. Bandwidth Shapping and QoS (Quality of Service, AKA traffic priorization) should be *TOP* in the TO DO list. -* irc proxy for dcc * Bandwidth limiting!!! +maybe for solaris, otherwise "ALTQ" * More examples * More documentation -* And did I mention bandwidth limiting??? * Load balancing features added to the NAT code, so that I can have something coming in for 20.20.20.20:80 and it gets shuffled around between internal addresses 10.10.10.1:8000 and 10.10.10.2:8000. or whatever. - done, stage 1 (round robin/split) The one thing that Cisco's PIX has on IPF that I can see is that rewrites the sequence numbers with semi-random ones. +- done I would also love to see a more extensive NAT. It can choose to do rdr and map based on saddr, daddr, sport and dport. (Does the kernel module already have functionality for that and it just needs support in the userland ipnat?) +-sort of done * intrusion detection detection of port scans @@ -76,23 +74,25 @@ the userland ipnat?) large packets of garbage or other packets to otherwise confuse the intruder (ping of death?) -* I ran into your solaris streams stuff and noticed you are -playing with mblk's in an unsafe way. You seem to be modifying the -underlying datab without checking db_ref. If db_ref is greater than one, -you'll need to copy the mblk, -- fixed - -* fix up where manual pages go for Solaris2 - - IPv6: ----- * NAT is yet not available, either as a null proxy or address translation BSD: * "to " and "to :" are not supported, but "fastroute" is. -fixed. Solaris: * "to :" is not supported, but "fastroute" is and "to " are. +Tru64: +------ +* IPv6 checksum calculation for RST's and ICMP packets is not done (there + are routines in the Tru64 kernel to do this but what is the interface?) + +does bimap allow equal sized subnets? + +make return-icmp 'intelligent' if no type is given about what type to use? + +reply-to - enforce packets to pass through interfaces in particular +combinations - opposite to "to", set reverse path interface + diff --git a/contrib/ipfilter/tools/BNF.ipf b/contrib/ipfilter/tools/BNF.ipf new file mode 100644 index 000000000000..0e8433291d1c --- /dev/null +++ b/contrib/ipfilter/tools/BNF.ipf @@ -0,0 +1,80 @@ +filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ] + [ proto ] [ ip ] [ group ] [ tag ] [ pps ] . + +insert = "@" decnumber . +action = block | "pass" | log | "count" | auth | call . +in-out = "in" | "out" . +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 ] . +tag = "tag" tagid . +call = "call" [ "now" ] function-name . +dup = "dup-to" interface-name[":"ipaddr] . +froute = "fastroute" | "to" interface-name . +protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber . +srcdst = "all" | fromto . +fromto = "from" object "to" object . + +return-icmp = "return-icmp" | "return-icmp-as-dest" . +loglevel = facility"."priority | priority . +object = addr [ port-comp | port-range ] . +addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . +port-comp = "port" compare port-num . +port-range = "port" port-num range port-num . +flags = "flags" flag { flag } [ "/" flag { flag } ] . +with = "with" | "and" . +icmp = "icmp-type" icmp-type [ "code" decnumber ] . +return-code = "("icmp-code")" . +keep = "keep" "state" [ "limit" number ] | "keep" "frags" . + +nummask = host-name [ "/" decnumber ] . +host-name = ipaddr | hostname | "any" . +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" | "nat" | "bad-src" | "lowttl" | "frag" | + "mbcast" | "opt" ipopts . +optname = ipopts [ "," optname ] . +ipopts = optlist | "sec-class" [ secname ] . +secname = seclvl [ "," secname ] . +seclvl = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" | + "reserv-4" | "secret" | "topsecret" . +icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" | + "timex" | "paramprob" | "timest" | "timestrep" | "inforeq" | + "inforep" | "maskreq" | "maskrep" | "routerad" | + "routersol" | decnumber . +icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" | + "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" | + "net-prohib" | "host-prohib" | "net-tos" | "host-tos" | + "filter-prohib" | "host-preced" | "cutoff-preced" . +optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" | + "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" | + "visa" | "imitd" | "eip" | "finn" . +facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" | + "lpr" | "news" | "uucp" | "cron" | "ftp" | "authpriv" | + "audit" | "logalert" | "local0" | "local1" | "local2" | + "local3" | "local4" | "local5" | "local6" | "local7" . +priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" | + "info" | "debug" . + +hexnumber = "0" "x" hexstring . +hexstring = hexdigit [ hexstring ] . +decnumber = digit [ decnumber ] . + +compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" | + "le" | "ge" . +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" | "C" | "W" . diff --git a/contrib/ipfilter/tools/BNF.ipnat b/contrib/ipfilter/tools/BNF.ipnat new file mode 100644 index 000000000000..69ed8a205504 --- /dev/null +++ b/contrib/ipfilter/tools/BNF.ipnat @@ -0,0 +1,28 @@ +ipmap :: = mapblock | redir | map . + +map ::= mapit ifname ipmask "->" ipmask [ mapport | mapicmpid ] . +map ::= mapit ifname fromto "->" ipmask [ mapport | mapicmpid ] . +mapblock ::= "map-block" ifname ipmask "->" ipmask [ ports ] . +redir ::= "rdr" ifname ipmask dport "->" ip [ "," ip ] [ ports ] options . + +dport ::= "port" portnum [ "-" portnum ] . +ports ::= "ports" numports | "auto" . +mapit ::= "map" | "bimap" . +fromto ::= "from" object "to" object . +ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask . +mapport ::= "portmap" tcpudp portnumber ":" portnumber . +mapicmpid ::= "icmpidmap" icmp idnumber ":" idnumber . +options ::= [ tcpudp ] [ rr ] . + +object = addr [ port-comp | port-range ] . +addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . +port-comp = "port" compare port-num . +port-range = "port" port-num range port-num . + +rr ::= "round-robin" . +tcpudp ::= "tcp" | "udp" | "tcp/udp" . +portnumber ::= number { numbers } | "auto" . +idnumber ::= number { numbers } . +ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers . + +numbers ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' . diff --git a/contrib/ipfilter/tools/Makefile b/contrib/ipfilter/tools/Makefile new file mode 100644 index 000000000000..49a869c78a45 --- /dev/null +++ b/contrib/ipfilter/tools/Makefile @@ -0,0 +1,103 @@ + +DEST=. + +all: $(DEST)/ipf_y.c $(DEST)/ipf_y.h $(DEST)/ipf_l.c \ + $(DEST)/ipmon_y.c $(DEST)/ipmon_y.h $(DEST)/ipmon_l.c \ + $(DEST)/ipnat_y.c $(DEST)/ipnat_y.h $(DEST)/ipnat_l.c \ + $(DEST)/ipscan_y.c $(DEST)/ipscan_y.h $(DEST)/ipscan_l.c \ + $(DEST)/ippool_y.c $(DEST)/ippool_y.h $(DEST)/ippool_l.c \ + $(DEST)/ipf_l.h $(DEST)/ipnat_l.h $(DEST)/ipscan_l.h \ + $(DEST)/ippool_l.h $(DEST)/ipmon_l.h + +$(DEST)/ipf_y.h: $(DEST)/ipf_y.c + +$(DEST)/ipf_y.c: ipf_y.y + yacc -d ipf_y.y + sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.c/' \ + -e 's/"ipf_y.y"/"..\/tools\/ipf_y.y"/' \ + y.tab.c > $(DEST)/ipf_y.c + sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.h/' y.tab.h > $(DEST)/ipf_y.h + /bin/rm -f y.tab.c y.tab.h + +$(DEST)/ipf_l.c: lexer.c + sed -e 's/yy/ipf_yy/g' -e 's/y.tab.h/ipf_y.h/' \ + -e 's/lexer.h/ipf_l.h/' lexer.c > $@ + +$(DEST)/ipmon_y.n: $(DEST)/ipmon_y.c + +$(DEST)/ipmon_y.c $(DEST)/ipmon_y.h: ipmon_y.y + yacc -d ipmon_y.y + sed -e 's/yy/ipmon_yy/g' -e 's/"ipmon_y.y"/"..\/tools\/ipmon_y.y"/' \ + y.tab.c > $(DEST)/ipmon_y.c + sed -e 's/yy/ipmon_yy/g' y.tab.h > $(DEST)/ipmon_y.h + /bin/rm -f y.tab.c y.tab.h + +$(DEST)/ipmon_l.c: lexer.c + sed -e 's/yy/ipmon_yy/g' -e 's/y.tab.h/ipmon_y.h/' \ + -e 's/lexer.h/ipmon_l.h/' lexer.c > $@ + +$(DEST)/ipscan_y.h: $(DEST)/ipscan_y.c + +$(DEST)/ipscan_y.c $(DEST)/ipscan_y.h: ipscan_y.y + yacc -d ipscan_y.y + sed -e 's/yy/ipscan_yy/g' \ + -e 's/"ipscan_y.y"/"..\/tools\/ipscan_y.y"/' \ + y.tab.c > $(DEST)/ipscan_y.c + sed -e 's/yy/ipscan_yy/g' y.tab.h > $(DEST)/ipscan_y.h + /bin/rm -f y.tab.c y.tab.h + +$(DEST)/ipscan_l.c: lexer.c + sed -e 's/yy/ipscan_yy/g' -e 's/y.tab.h/ipscan_y.h/' \ + -e 's/lexer.h/ipscan_l.h/' lexer.c > $@ + +$(DEST)/ippool_y.h: $(DEST)/ippool_y.c + +$(DEST)/ippool_y.c $(DEST)/ippool_y.h: ippool_y.y + yacc -d ippool_y.y + sed -e 's/yy/ippool_yy/g' -e 's/"ippool_y.y"/"..\/tools\/ippool_y.y"/' \ + y.tab.c > $(DEST)/ippool_y.c + sed -e 's/yy/ippool_yy/g' y.tab.h > $(DEST)/ippool_y.h + /bin/rm -f y.tab.c y.tab.h + +$(DEST)/ippool_l.c: lexer.c + sed -e 's/yy/ippool_yy/g' -e 's/y.tab.h/ippool_y.h/' \ + -e 's/lexer.h/ippool_l.h/' lexer.c > $@ + +$(DEST)/ipnat_y.h: $(DEST)/ipnat_y.c + +$(DEST)/ipnat_y.c $(DEST)/ipnat_y.h: ipnat_y.y + yacc -d ipnat_y.y + sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.c/ipnat_y.c/' \ + -e s/\"ipnat_y.y\"/\"..\\/tools\\/ipnat_y.y\"/ \ + y.tab.c > $(DEST)/ipnat_y.c + sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.h/ipnat_y.h/' \ + y.tab.h > $(DEST)/ipnat_y.h + /bin/rm -f y.tab.c y.tab.h + +$(DEST)/ipnat_l.c: lexer.c + sed -e 's/yy/ipnat_yy/g' -e 's/y.tab.h/ipnat_y.h/' \ + -e 's/lexer.h/ipnat_l.h/' lexer.c > $@ + +$(DEST)/ipf_l.h: lexer.h + sed -e 's/yy/ipf_yy/g' lexer.h > $@ + +$(DEST)/ipmon_l.h: lexer.h + sed -e 's/yy/ipmon_yy/g' lexer.h > $@ + +$(DEST)/ipscan_l.h: lexer.h + sed -e 's/yy/ipscan_yy/g' lexer.h > $@ + +$(DEST)/ippool_l.h: lexer.h + sed -e 's/yy/ippool_yy/g' lexer.h > $@ + +$(DEST)/ipnat_l.h: lexer.h + sed -e 's/yy/ipnat_yy/g' lexer.h > $@ + +clean: + /bin/rm -f $(DEST)/ipf_y.c $(DEST)/ipf_y.h $(DEST)/ipf_l.c + /bin/rm -f $(DEST)/ipmon_y.c $(DEST)/ipmon_y.h $(DEST)/ipmon_l.c + /bin/rm -f $(DEST)/ipscan_y.c $(DEST)/ipscan_y.h $(DEST)/ipscan_l.c + /bin/rm -f $(DEST)/ippool_y.c $(DEST)/ippool_y.h $(DEST)/ippool_l.c + /bin/rm -f $(DEST)/ipnat_y.c $(DEST)/ipnat_y.h $(DEST)/ipnat_l.c + /bin/rm -f $(DEST)/ipf_l.h $(DEST)/ipmon_l.h $(DEST)/ippool_l.h + /bin/rm -f $(DEST)/ipscan_l.h $(DEST)/ipnat_l.h diff --git a/contrib/ipfilter/tools/ipf.c b/contrib/ipfilter/tools/ipf.c new file mode 100644 index 000000000000..ea39780115b1 --- /dev/null +++ b/contrib/ipfilter/tools/ipf.c @@ -0,0 +1,562 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#ifdef __FreeBSD__ +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 +# include +# endif +# endif +#endif +#include "ipf.h" +#include +#include +#include "netinet/ipl.h" + +#if !defined(lint) +static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipf.c,v 1.35.2.3 2004/12/15 18:27:17 darrenr Exp"; +#endif + +#if !defined(__SVR4) && defined(__GNUC__) +extern char *index __P((const char *, int)); +#endif + +extern char *optarg; +extern int optind; +extern frentry_t *frtop; + + +void ipf_frsync __P((void)); +void zerostats __P((void)); +int main __P((int, char *[])); + +int opts = 0; +int outputc = 0; +int use_inet6 = 0; + +static void procfile __P((char *, char *)), flushfilter __P((char *)); +static void set_state __P((u_int)), showstats __P((friostat_t *)); +static void packetlogon __P((char *)), swapactive __P((void)); +static int opendevice __P((char *, int)); +static void closedevice __P((void)); +static char *ipfname = IPL_NAME; +static void usage __P((void)); +static int showversion __P((void)); +static int get_flags __P((void)); +static void ipf_interceptadd __P((int, ioctlfunc_t, void *)); + +static int fd = -1; +static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl, + ioctl, ioctl, ioctl, + ioctl, ioctl }; + + +static void usage() +{ + fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n", + "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]", + "[-f filename] [-T ]"); + exit(1); +} + + +int main(argc,argv) +int argc; +char *argv[]; +{ + int c; + + if (argc < 2) + usage(); + + while ((c = getopt(argc, argv, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) { + switch (c) + { + case '?' : + usage(); + break; +#ifdef USE_INET6 + case '6' : + use_inet6 = 1; + break; +#endif + case 'A' : + opts &= ~OPT_INACTIVE; + break; + case 'c' : + if (strcmp(optarg, "c") == 0) + outputc = 1; + break; + case 'E' : + set_state((u_int)1); + break; + case 'D' : + set_state((u_int)0); + break; + case 'd' : + opts ^= OPT_DEBUG; + break; + case 'f' : + procfile(argv[0], optarg); + break; + case 'F' : + flushfilter(optarg); + break; + case 'I' : + opts ^= OPT_INACTIVE; + break; + case 'l' : + packetlogon(optarg); + break; + case 'n' : + opts ^= OPT_DONOTHING; + break; + case 'o' : + break; + case 'P' : + ipfname = IPAUTH_NAME; + break; + case 'R' : + opts ^= OPT_NORESOLVE; + break; + case 'r' : + opts ^= OPT_REMOVE; + break; + case 's' : + swapactive(); + break; + case 'T' : + if (opendevice(ipfname, 1) >= 0) + ipf_dotuning(fd, optarg, ioctl); + break; + case 'v' : + opts += OPT_VERBOSE; + break; + case 'V' : + if (showversion()) + exit(1); + break; + case 'y' : + ipf_frsync(); + break; + case 'z' : + opts ^= OPT_ZERORULEST; + break; + case 'Z' : + zerostats(); + break; + } + } + + if (optind < 2) + usage(); + + if (fd != -1) + (void) close(fd); + + return(0); + /* NOTREACHED */ +} + + +static int opendevice(ipfdev, check) +char *ipfdev; +int check; +{ + if (opts & OPT_DONOTHING) + return -2; + + if (check && checkrev(ipfname) == -1) { + fprintf(stderr, "User/kernel version check failed\n"); + return -2; + } + + if (!ipfdev) + ipfdev = ipfname; + + if (fd == -1) + if ((fd = open(ipfdev, O_RDWR)) == -1) + if ((fd = open(ipfdev, O_RDONLY)) == -1) + perror("open device"); + return fd; +} + + +static void closedevice() +{ + close(fd); + fd = -1; +} + + +static int get_flags() +{ + int i; + + if ((opendevice(ipfname, 1) != -2) && + (ioctl(fd, SIOCGETFF, &i) == -1)) { + perror("SIOCGETFF"); + return 0; + } + return i; +} + + +static void set_state(enable) +u_int enable; +{ + if (opendevice(ipfname, 0) != -2) + if (ioctl(fd, SIOCFRENB, &enable) == -1) { + if (errno == EBUSY) + fprintf(stderr, + "IP FIlter: already initialized\n"); + else + perror("SIOCFRENB"); + } + return; +} + + +static void procfile(name, file) +char *name, *file; +{ + (void) opendevice(ipfname, 1); + + initparse(); + + ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file); + + if (outputc) { + printC(0); + printC(1); + emit(-1, -1, NULL, NULL); + } +} + + +static void ipf_interceptadd(fd, ioctlfunc, ptr) +int fd; +ioctlfunc_t ioctlfunc; +void *ptr; +{ + if (outputc) + printc(ptr); + + ipf_addrule(fd, ioctlfunc, ptr); +} + + +static void packetlogon(opt) +char *opt; +{ + int flag, xfd, logopt, change = 0; + + flag = get_flags(); + if (flag != 0) { + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) + printf("log flag is currently %#x\n", flag); + } + + flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK); + + if (strstr(opt, "pass")) { + flag |= FF_LOGPASS; + if (opts & OPT_VERBOSE) + printf("set log flag: pass\n"); + change = 1; + } + if (strstr(opt, "nomatch")) { + flag |= FF_LOGNOMATCH; + if (opts & OPT_VERBOSE) + printf("set log flag: nomatch\n"); + change = 1; + } + if (strstr(opt, "block") || index(opt, 'd')) { + flag |= FF_LOGBLOCK; + if (opts & OPT_VERBOSE) + printf("set log flag: block\n"); + change = 1; + } + if (strstr(opt, "none")) { + if (opts & OPT_VERBOSE) + printf("disable all log flags\n"); + change = 1; + } + + if (change == 1) { + if (opendevice(ipfname, 1) != -2 && + (ioctl(fd, SIOCSETFF, &flag) != 0)) + perror("ioctl(SIOCSETFF)"); + } + + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + flag = get_flags(); + printf("log flags are now %#x\n", flag); + } + + if (strstr(opt, "state")) { + if (opts & OPT_VERBOSE) + printf("set state log flag\n"); + xfd = open(IPSTATE_NAME, O_RDWR); + if (xfd >= 0) { + logopt = 0; + if (ioctl(xfd, SIOCGETLG, &logopt)) + perror("ioctl(SIOCGETLG)"); + else { + logopt = 1 - logopt; + if (ioctl(xfd, SIOCSETLG, &logopt)) + perror("ioctl(SIOCSETLG)"); + } + close(xfd); + } + } + + if (strstr(opt, "nat")) { + if (opts & OPT_VERBOSE) + printf("set nat log flag\n"); + xfd = open(IPNAT_NAME, O_RDWR); + if (xfd >= 0) { + logopt = 0; + if (ioctl(xfd, SIOCGETLG, &logopt)) + perror("ioctl(SIOCGETLG)"); + else { + logopt = 1 - logopt; + if (ioctl(xfd, SIOCSETLG, &logopt)) + perror("ioctl(SIOCSETLG)"); + } + close(xfd); + } + } +} + + +static void flushfilter(arg) +char *arg; +{ + int fl = 0, rem; + + if (!arg || !*arg) + return; + if (!strcmp(arg, "s") || !strcmp(arg, "S")) { + if (*arg == 'S') + fl = 0; + else + fl = 1; + rem = fl; + + closedevice(); + if (opendevice(IPSTATE_NAME, 1) == -2) + exit(1); + + if (!(opts & OPT_DONOTHING)) { + if (use_inet6) { + if (ioctl(fd, SIOCIPFL6, &fl) == -1) { + perror("ioctl(SIOCIPFL6)"); + exit(1); + } + } else { + if (ioctl(fd, SIOCIPFFL, &fl) == -1) { + perror("ioctl(SIOCIPFFL)"); + exit(1); + } + } + } + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + printf("remove flags %s (%d)\n", arg, rem); + printf("removed %d filter rules\n", fl); + } + closedevice(); + return; + } + +#ifdef SIOCIPFFA + if (!strcmp(arg, "u")) { + closedevice(); + /* + * Flush auth rules and packets + */ + if (opendevice(IPL_AUTH, 1) == -1) + perror("open(IPL_AUTH)"); + else { + if (ioctl(fd, SIOCIPFFA, &fl) == -1) + perror("ioctl(SIOCIPFFA)"); + } + closedevice(); + return; + } +#endif + + if (strchr(arg, 'i') || strchr(arg, 'I')) + fl = FR_INQUE; + if (strchr(arg, 'o') || strchr(arg, 'O')) + fl = FR_OUTQUE; + if (strchr(arg, 'a') || strchr(arg, 'A')) + fl = FR_OUTQUE|FR_INQUE; + if (opts & OPT_INACTIVE) + fl |= FR_INACTIVE; + rem = fl; + + if (opendevice(ipfname, 1) == -2) + exit(1); + + if (!(opts & OPT_DONOTHING)) { + if (use_inet6) { + if (ioctl(fd, SIOCIPFL6, &fl) == -1) { + perror("ioctl(SIOCIPFL6)"); + exit(1); + } + } else { + if (ioctl(fd, SIOCIPFFL, &fl) == -1) { + perror("ioctl(SIOCIPFFL)"); + exit(1); + } + } + } + + if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { + printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "", + (rem & FR_OUTQUE) ? "O" : "", rem); + printf("removed %d filter rules\n", fl); + } + return; +} + + +static void swapactive() +{ + int in = 2; + + if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1) + perror("ioctl(SIOCSWAPA)"); + else + printf("Set %d now inactive\n", in); +} + + +void ipf_frsync() +{ + int frsyn = 0; + + if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1) + perror("SIOCFRSYN"); + else + printf("filter sync'd\n"); +} + + +void zerostats() +{ + friostat_t fio; + friostat_t *fiop = &fio; + + if (opendevice(ipfname, 1) != -2) { + if (ioctl(fd, SIOCFRZST, &fiop) == -1) { + perror("ioctl(SIOCFRZST)"); + exit(-1); + } + showstats(fiop); + } + +} + + +/* + * read the kernel stats for packets blocked and passed + */ +static void showstats(fp) +friostat_t *fp; +{ + printf("bad packets:\t\tin %lu\tout %lu\n", + fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); + printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu", + fp->f_st[0].fr_block, fp->f_st[0].fr_pass, + fp->f_st[0].fr_nom); + printf(" counted %lu\n", fp->f_st[0].fr_acct); + printf("output packets:\t\tblocked %lu passed %lu nomatch %lu", + fp->f_st[1].fr_block, fp->f_st[1].fr_pass, + fp->f_st[1].fr_nom); + printf(" counted %lu\n", fp->f_st[0].fr_acct); + printf(" input packets logged:\tblocked %lu passed %lu\n", + fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); + printf("output packets logged:\tblocked %lu passed %lu\n", + fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); + printf(" packets logged:\tinput %lu-%lu output %lu-%lu\n", + fp->f_st[0].fr_pkl, fp->f_st[0].fr_skip, + fp->f_st[1].fr_pkl, fp->f_st[1].fr_skip); +} + + +static int showversion() +{ + struct friostat fio; + ipfobj_t ipfo; + u_32_t flags; + char *s; + int vfd; + + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(fio); + ipfo.ipfo_ptr = (void *)&fio; + ipfo.ipfo_type = IPFOBJ_IPFSTAT; + + printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t)); + + if ((vfd = open(ipfname, O_RDONLY)) == -1) { + perror("open device"); + return 1; + } + + if (ioctl(vfd, SIOCGETFS, &ipfo)) { + perror("ioctl(SIOCGETFS)"); + close(vfd); + return 1; + } + close(vfd); + flags = get_flags(); + + printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version), + (int)sizeof(fio.f_version), fio.f_version); + printf("Running: %s\n", (fio.f_running > 0) ? "yes" : "no"); + printf("Log Flags: %#x = ", flags); + s = ""; + if (flags & FF_LOGPASS) { + printf("pass"); + s = ", "; + } + if (flags & FF_LOGBLOCK) { + printf("%sblock", s); + s = ", "; + } + if (flags & FF_LOGNOMATCH) { + printf("%snomatch", s); + s = ", "; + } + if (flags & FF_BLOCKNONIP) { + printf("%snonip", s); + s = ", "; + } + if (!*s) + printf("none set"); + putchar('\n'); + + printf("Default: "); + if (FR_ISPASS(fio.f_defpass)) + s = "pass"; + else if (FR_ISBLOCK(fio.f_defpass)) + s = "block"; + else + s = "nomatch -> block"; + printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un"); + printf("Active list: %d\n", fio.f_active); + printf("Feature mask: %#x\n", fio.f_features); + + return 0; +} diff --git a/contrib/ipfilter/tools/ipf_y.y b/contrib/ipfilter/tools/ipf_y.y new file mode 100644 index 000000000000..0660d50dcf4d --- /dev/null +++ b/contrib/ipfilter/tools/ipf_y.y @@ -0,0 +1,2126 @@ +/* $NetBSD$ */ + +%{ +#include "ipf.h" +#include +#include +#ifdef IPFILTER_BPF +# include +# include +#endif +#include "netinet/ip_pool.h" +#include "netinet/ip_htable.h" +#include "netinet/ipl.h" +#include "ipf_l.h" + +#define YYDEBUG 1 +#define DOALL(x) for (fr = frc; fr != NULL; fr = fr->fr_next) { x } +#define DOREM(x) for (; fr != NULL; fr = fr->fr_next) { x } + +extern void yyerror __P((char *)); +extern int yyparse __P((void)); +extern int yylex __P((void)); +extern int yydebug; +extern FILE *yyin; +extern int yylineNum; + +static void newrule __P((void)); +static void setipftype __P((void)); +static u_32_t lookuphost __P((char *)); +static void dobpf __P((int, char *)); +static void resetaddr __P((void)); +static struct alist_s *newalist __P((struct alist_s *)); +static u_int makehash __P((struct alist_s *)); +static int makepool __P((struct alist_s *)); +static frentry_t *addrule __P((void)); +static void setsyslog __P((void)); +static void unsetsyslog __P((void)); +static void fillgroup __P((frentry_t *)); + +frentry_t *fr = NULL, *frc = NULL, *frtop = NULL, *frold = NULL; + +static int ifpflag = 0; +static int nowith = 0; +static int dynamic = -1; +static int pooled = 0; +static int hashed = 0; +static int nrules = 0; +static int newlist = 0; +static int added = 0; +static int ipffd = -1; +static int *yycont = 0; +static ioctlfunc_t ipfioctl[IPL_LOGSIZE]; +static addfunc_t ipfaddfunc = NULL; +static struct wordtab ipfwords[95]; +static struct wordtab addrwords[4]; +static struct wordtab maskwords[5]; +static struct wordtab icmpcodewords[17]; +static struct wordtab icmptypewords[16]; +static struct wordtab ipv4optwords[25]; +static struct wordtab ipv4secwords[9]; +static struct wordtab ipv6optwords[8]; +static struct wordtab logwords[33]; + +%} +%union { + char *str; + u_32_t num; + struct in_addr ipa; + frentry_t fr; + frtuc_t *frt; + struct alist_s *alist; + u_short port; + struct { + u_short p1; + u_short p2; + int pc; + } pc; + struct { + union i6addr a; + union i6addr m; + } ipp; + union i6addr ip6; +}; + +%type portnum +%type facility priority icmpcode seclevel secname icmptype +%type opt compare range opttype flagset optlist ipv6hdrlist ipv6hdr +%type portc porteq +%type hostname ipv4 ipv4mask ipv4_16 ipv4_24 +%type ipv6mask +%type addr ipaddr +%type servicename name interfacename +%type portrange portcomp +%type addrlist poollist + +%token YY_NUMBER YY_HEX +%token YY_STR +%token YY_COMMENT +%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT +%token YY_RANGE_OUT YY_RANGE_IN +%token YY_IPV6 + +%token IPFY_PASS IPFY_BLOCK IPFY_COUNT IPFY_CALL +%token IPFY_RETICMP IPFY_RETRST IPFY_RETICMPASDST +%token IPFY_IN IPFY_OUT +%token IPFY_QUICK IPFY_ON IPFY_OUTVIA IPFY_INVIA +%token IPFY_DUPTO IPFY_TO IPFY_FROUTE IPFY_REPLY_TO IPFY_ROUTETO +%token IPFY_TOS IPFY_TTL IPFY_PROTO +%token IPFY_HEAD IPFY_GROUP +%token IPFY_AUTH IPFY_PREAUTH +%token IPFY_LOG IPFY_BODY IPFY_FIRST IPFY_LEVEL IPFY_ORBLOCK +%token IPFY_LOGTAG IPFY_MATCHTAG IPFY_SETTAG IPFY_SKIP +%token IPFY_FROM IPFY_ALL IPFY_ANY IPFY_BPFV4 IPFY_BPFV6 IPFY_POOL IPFY_HASH +%token IPFY_PPS +%token IPFY_ESP IPFY_AH +%token IPFY_WITH IPFY_AND IPFY_NOT IPFY_NO IPFY_OPT +%token IPFY_TCPUDP IPFY_TCP IPFY_UDP +%token IPFY_FLAGS IPFY_MULTICAST +%token IPFY_MASK IPFY_BROADCAST IPFY_NETWORK IPFY_NETMASKED IPFY_PEER +%token IPFY_PORT +%token IPFY_NOW +%token IPFY_ICMP IPFY_ICMPTYPE IPFY_ICMPCODE +%token IPFY_IPOPTS IPFY_SHORT IPFY_NAT IPFY_BADSRC IPFY_LOWTTL IPFY_FRAG +%token IPFY_MBCAST IPFY_BAD IPFY_BADNAT IPFY_OOW IPFY_NEWISN IPFY_NOICMPERR +%token IPFY_KEEP IPFY_STATE IPFY_FRAGS IPFY_LIMIT IPFY_STRICT IPFY_AGE +%token IPFY_SYNC IPFY_FRAGBODY +%token IPFY_IPOPT_NOP IPFY_IPOPT_RR IPFY_IPOPT_ZSU IPFY_IPOPT_MTUP +%token IPFY_IPOPT_MTUR IPFY_IPOPT_ENCODE IPFY_IPOPT_TS IPFY_IPOPT_TR +%token IPFY_IPOPT_SEC IPFY_IPOPT_LSRR IPFY_IPOPT_ESEC IPFY_IPOPT_CIPSO +%token IPFY_IPOPT_SATID IPFY_IPOPT_SSRR IPFY_IPOPT_ADDEXT IPFY_IPOPT_VISA +%token IPFY_IPOPT_IMITD IPFY_IPOPT_EIP IPFY_IPOPT_FINN IPFY_IPOPT_DPS +%token IPFY_IPOPT_SDB IPFY_IPOPT_NSAPA IPFY_IPOPT_RTRALRT IPFY_IPOPT_UMP +%token IPFY_SECCLASS IPFY_SEC_UNC IPFY_SEC_CONF IPFY_SEC_RSV1 IPFY_SEC_RSV2 +%token IPFY_SEC_RSV4 IPFY_SEC_SEC IPFY_SEC_TS IPFY_SEC_RSV3 + +%token IPF6_V6HDRS IPFY_IPV6OPT IPFY_IPV6OPT_DSTOPTS IPFY_IPV6OPT_HOPOPTS +%token IPFY_IPV6OPT_IPV6 IPFY_IPV6OPT_NONE IPFY_IPV6OPT_ROUTING + +%token IPFY_ICMPT_UNR IPFY_ICMPT_ECHO IPFY_ICMPT_ECHOR IPFY_ICMPT_SQUENCH +%token IPFY_ICMPT_REDIR IPFY_ICMPT_TIMEX IPFY_ICMPT_PARAMP IPFY_ICMPT_TIMEST +%token IPFY_ICMPT_TIMESTREP IPFY_ICMPT_INFOREQ IPFY_ICMPT_INFOREP +%token IPFY_ICMPT_MASKREQ IPFY_ICMPT_MASKREP IPFY_ICMPT_ROUTERAD +%token IPFY_ICMPT_ROUTERSOL + +%token IPFY_ICMPC_NETUNR IPFY_ICMPC_HSTUNR IPFY_ICMPC_PROUNR IPFY_ICMPC_PORUNR +%token IPFY_ICMPC_NEEDF IPFY_ICMPC_SRCFAIL IPFY_ICMPC_NETUNK IPFY_ICMPC_HSTUNK +%token IPFY_ICMPC_ISOLATE IPFY_ICMPC_NETPRO IPFY_ICMPC_HSTPRO +%token IPFY_ICMPC_NETTOS IPFY_ICMPC_HSTTOS IPFY_ICMPC_FLTPRO IPFY_ICMPC_HSTPRE +%token IPFY_ICMPC_CUTPRE + +%token IPFY_FAC_KERN IPFY_FAC_USER IPFY_FAC_MAIL IPFY_FAC_DAEMON IPFY_FAC_AUTH +%token IPFY_FAC_SYSLOG IPFY_FAC_LPR IPFY_FAC_NEWS IPFY_FAC_UUCP IPFY_FAC_CRON +%token IPFY_FAC_LOCAL0 IPFY_FAC_LOCAL1 IPFY_FAC_LOCAL2 IPFY_FAC_LOCAL3 +%token IPFY_FAC_LOCAL4 IPFY_FAC_LOCAL5 IPFY_FAC_LOCAL6 IPFY_FAC_LOCAL7 +%token IPFY_FAC_SECURITY IPFY_FAC_FTP IPFY_FAC_AUTHPRIV IPFY_FAC_AUDIT +%token IPFY_FAC_LFMT IPFY_FAC_CONSOLE + +%token IPFY_PRI_EMERG IPFY_PRI_ALERT IPFY_PRI_CRIT IPFY_PRI_ERR IPFY_PRI_WARN +%token IPFY_PRI_NOTICE IPFY_PRI_INFO IPFY_PRI_DEBUG +%% +file: line + | assign + | file line + | file assign + ; + +line: xx rule { while ((fr = frtop) != NULL) { + frtop = fr->fr_next; + fr->fr_next = NULL; + (*ipfaddfunc)(ipffd, ipfioctl[IPL_LOGIPF], fr); + fr->fr_next = frold; + frold = fr; + } + resetlexer(); + } + | YY_COMMENT + ; + +xx: { newrule(); } + ; + +assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); + resetlexer(); + free($1); + free($3); + } + ; + +assigning: + '=' { yyvarnext = 1; } + ; + +rule: inrule eol + | outrule eol + ; + +eol: | ';' + ; + +inrule: + rulehead markin inopts rulemain ruletail intag ruletail2 + ; + +outrule: + rulehead markout outopts rulemain ruletail outtag ruletail2 + ; + +rulehead: + collection action + | insert collection action + ; + +markin: IPFY_IN { fr->fr_flags |= FR_INQUE; } + ; + +markout: + IPFY_OUT { fr->fr_flags |= FR_OUTQUE; } + ; + +rulemain: + ipfrule + | bpfrule + ; + +ipfrule: + tos ttl proto ip + ; + +bpfrule: + IPFY_BPFV4 '{' YY_STR '}' { dobpf(4, $3); free($3); } + | IPFY_BPFV6 '{' YY_STR '}' { dobpf(6, $3); free($3); } + ; + +ruletail: + with keep head group + ; + +ruletail2: + pps age new + ; + +intag: settagin matchtagin + ; + +outtag: settagout matchtagout + ; + +insert: + '@' YY_NUMBER { fr->fr_hits = (U_QUAD_T)$2 + 1; } + ; + +collection: + | YY_NUMBER { fr->fr_collect = $1; } + ; + +action: block + | IPFY_PASS { fr->fr_flags |= FR_PASS; } + | log + | IPFY_COUNT { fr->fr_flags |= FR_ACCOUNT; } + | auth + | IPFY_SKIP YY_NUMBER { fr->fr_flags |= FR_SKIP; + fr->fr_arg = $2; } + | IPFY_CALL func + | IPFY_CALL IPFY_NOW func { fr->fr_flags |= FR_CALLNOW; } + ; + +block: blocked + | blocked blockreturn + ; + +blocked: + IPFY_BLOCK { fr->fr_flags = FR_BLOCK; } + ; +blockreturn: + IPFY_RETICMP { fr->fr_flags |= FR_RETICMP; } + | IPFY_RETICMP returncode { fr->fr_flags |= FR_RETICMP; } + | IPFY_RETICMPASDST { fr->fr_flags |= FR_FAKEICMP; } + | IPFY_RETICMPASDST returncode { fr->fr_flags |= FR_FAKEICMP; } + | IPFY_RETRST { fr->fr_flags |= FR_RETRST; } + ; + +log: IPFY_LOG { fr->fr_flags |= FR_LOG; } + | IPFY_LOG logoptions { fr->fr_flags |= FR_LOG; } + ; + +auth: IPFY_AUTH { fr->fr_flags |= FR_AUTH; } + | IPFY_AUTH IPFY_RETRST { fr->fr_flags |= (FR_AUTH|FR_RETRST);} + | IPFY_PREAUTH { fr->fr_flags |= FR_PREAUTH; } + ; + +func: YY_STR '/' YY_NUMBER { fr->fr_func = nametokva($1, + ipfioctl[IPL_LOGIPF]); + fr->fr_arg = $3; + free($1); } + ; + +inopts: + | inopts inopt + ; + +inopt: + logopt + | quick + | on + | dup + | froute + | proute + | replyto + ; + +outopts: + | outopts outopt + ; + +outopt: + logopt + | quick + | on + | dup + | proute + | replyto + ; + +tos: | settos YY_NUMBER { DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) } + | settos YY_HEX { DOALL(fr->fr_tos = $2; fr->fr_mtos = 0xff;) } + | settos lstart toslist lend + ; + +settos: IPFY_TOS { setipftype(); } + ; + +toslist: + YY_NUMBER { DOALL(fr->fr_tos = $1; fr->fr_mtos = 0xff;) } + | YY_HEX { DOREM(fr->fr_tos = $1; fr->fr_mtos = 0xff;) } + | toslist lmore YY_NUMBER + { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) } + | toslist lmore YY_HEX + { DOREM(fr->fr_tos = $3; fr->fr_mtos = 0xff;) } + ; + +ttl: | setttl YY_NUMBER + { DOALL(fr->fr_ttl = $2; fr->fr_mttl = 0xff;) } + | setttl lstart ttllist lend + ; + +lstart: '(' { newlist = 1; fr = frc; added = 0; } + ; + +lend: ')' { nrules += added; } + ; + +lmore: lanother { if (newlist == 1) { + newlist = 0; + } + fr = addrule(); + if (yycont != NULL) + *yycont = 1; + } + ; + +lanother: + | ',' + ; + +setttl: IPFY_TTL { setipftype(); } + ; + +ttllist: + YY_NUMBER { DOREM(fr->fr_ttl = $1; fr->fr_mttl = 0xff;) } + | ttllist lmore YY_NUMBER + { DOREM(fr->fr_ttl = $3; fr->fr_mttl = 0xff;) } + ; + +proto: | protox protocol { yyresetdict(); } + ; + +protox: IPFY_PROTO { setipftype(); + fr = frc; + yysetdict(NULL); } + ; + +ip: srcdst flags icmp + ; + +group: | IPFY_GROUP YY_STR { DOALL(strncpy(fr->fr_group, $2, \ + FR_GROUPLEN); \ + fillgroup(fr);); + free($2); } + | IPFY_GROUP YY_NUMBER { DOALL(sprintf(fr->fr_group, "%d", \ + $2); \ + fillgroup(fr);) } + ; + +head: | IPFY_HEAD YY_STR { DOALL(strncpy(fr->fr_grhead, $2, \ + FR_GROUPLEN);); + free($2); } + | IPFY_HEAD YY_NUMBER { DOALL(sprintf(fr->fr_grhead, "%d", \ + $2);) } + ; + +settagin: + | IPFY_SETTAG '(' taginlist ')' + ; + +taginlist: + taginspec + | taginlist ',' taginspec + ; + +taginspec: + logtag + ; + +nattag: IPFY_NAT '=' YY_STR { DOALL(strncpy(fr->fr_nattag.ipt_tag,\ + $3, IPFTAG_LEN);); + free($3); } + | IPFY_NAT '=' YY_NUMBER { DOALL(sprintf(fr->fr_nattag.ipt_tag,\ + "%d", $3 & 0xffffffff);) } + ; + +logtag: IPFY_LOG '=' YY_NUMBER { DOALL(fr->fr_logtag = $3;) } + ; + +settagout: + | IPFY_SETTAG '(' tagoutlist ')' + ; + +tagoutlist: + tagoutspec + | tagoutlist ',' tagoutspec + ; + +tagoutspec: + logtag + | nattag + ; + +matchtagin: + | IPFY_MATCHTAG '(' tagoutlist ')' + ; + +matchtagout: + | IPFY_MATCHTAG '(' taginlist ')' + ; + +pps: | IPFY_PPS YY_NUMBER { DOALL(fr->fr_pps = $2;) } + ; + +new: | savegroup file restoregroup + ; + +savegroup: + '{' + ; + +restoregroup: + '}' + ; + +logopt: log + ; + +quick: + IPFY_QUICK { fr->fr_flags |= FR_QUICK; } + ; + +on: IPFY_ON onname + | IPFY_ON onname IPFY_INVIA vianame + | IPFY_ON onname IPFY_OUTVIA vianame + ; + +onname: interfacename + { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0])); + free($1); + } + | interfacename ',' interfacename + { strncpy(fr->fr_ifnames[0], $1, sizeof(fr->fr_ifnames[0])); + free($1); + strncpy(fr->fr_ifnames[1], $3, sizeof(fr->fr_ifnames[1])); + free($3); + } + ; + +vianame: + name + { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2])); + free($1); + } + | name ',' name + { strncpy(fr->fr_ifnames[2], $1, sizeof(fr->fr_ifnames[2])); + free($1); + strncpy(fr->fr_ifnames[3], $3, sizeof(fr->fr_ifnames[3])); + free($3); + } + ; + +dup: IPFY_DUPTO name + { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname)); + free($2); + } + | IPFY_DUPTO name duptoseparator hostname + { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname)); + fr->fr_dif.fd_ip = $4; + yyexpectaddr = 0; + free($2); + } + | IPFY_DUPTO name duptoseparator YY_IPV6 + { strncpy(fr->fr_dif.fd_ifname, $2, sizeof(fr->fr_dif.fd_ifname)); + bcopy(&$4, &fr->fr_dif.fd_ip6, sizeof(fr->fr_dif.fd_ip6)); + yyexpectaddr = 0; + free($2); + } + ; + +duptoseparator: + ':' { yyexpectaddr = 1; yycont = &yyexpectaddr; resetaddr(); } + ; + +froute: IPFY_FROUTE { fr->fr_flags |= FR_FASTROUTE; } + ; + +proute: routeto name + { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname)); + free($2); + } + | routeto name duptoseparator hostname + { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname)); + fr->fr_tif.fd_ip = $4; + yyexpectaddr = 0; + free($2); + } + | routeto name duptoseparator YY_IPV6 + { strncpy(fr->fr_tif.fd_ifname, $2, sizeof(fr->fr_tif.fd_ifname)); + bcopy(&$4, &fr->fr_tif.fd_ip6, sizeof(fr->fr_tif.fd_ip6)); + yyexpectaddr = 0; + free($2); + } + ; + +routeto: + IPFY_TO + | IPFY_ROUTETO + ; + +replyto: + IPFY_REPLY_TO name + { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname)); + free($2); + } + | IPFY_REPLY_TO name duptoseparator hostname + { strncpy(fr->fr_rif.fd_ifname, $2, sizeof(fr->fr_rif.fd_ifname)); + fr->fr_rif.fd_ip = $4; + free($2); + } + ; + +logoptions: + logoption + | logoptions logoption + ; + +logoption: + IPFY_BODY { fr->fr_flags |= FR_LOGBODY; } + | IPFY_FIRST { fr->fr_flags |= FR_LOGFIRST; } + | IPFY_ORBLOCK { fr->fr_flags |= FR_LOGORBLOCK; } + | level loglevel { unsetsyslog(); } + ; + +returncode: + starticmpcode icmpcode ')' { fr->fr_icode = $2; yyresetdict(); } + ; + +starticmpcode: + '(' { yysetdict(icmpcodewords); } + ; + +srcdst: | IPFY_ALL + | fromto + ; + +protocol: + YY_NUMBER { DOREM(fr->fr_proto = $1; \ + fr->fr_mproto = 0xff;) } + | YY_STR { if (!strcmp($1, "tcp-udp")) { + DOREM(fr->fr_flx |= FI_TCPUDP; \ + fr->fr_mflx |= FI_TCPUDP;) + } else { + int p = getproto($1); + if (p == -1) + yyerror("protocol unknown"); + DOREM(fr->fr_proto = p; \ + fr->fr_mproto = 0xff;) + } + free($1); + } + | YY_STR nextstring YY_STR + { if (!strcmp($1, "tcp") && + !strcmp($3, "udp")) { + DOREM(fr->fr_flx |= FI_TCPUDP; \ + fr->fr_mflx |= FI_TCPUDP;) + } else + YYERROR; + free($1); + free($3); + } + ; + +nextstring: + '/' { yysetdict(NULL); } + ; + +fromto: from srcobject to dstobject { yyexpectaddr = 0; yycont = NULL; } + | to dstobject { yyexpectaddr = 0; yycont = NULL; } + | from srcobject { yyexpectaddr = 0; yycont = NULL; } + ; + +from: IPFY_FROM { setipftype(); + if (fr == NULL) + fr = frc; + yyexpectaddr = 1; + if (yydebug) + printf("set yyexpectaddr\n"); + yycont = &yyexpectaddr; + yysetdict(addrwords); + resetaddr(); } + ; + +to: IPFY_TO { if (fr == NULL) + fr = frc; + yyexpectaddr = 1; + if (yydebug) + printf("set yyexpectaddr\n"); + yycont = &yyexpectaddr; + yysetdict(addrwords); + resetaddr(); } + ; + +with: | andwith withlist + ; + +andwith: + IPFY_WITH { nowith = 0; setipftype(); } + | IPFY_AND { nowith = 0; setipftype(); } + ; + +flags: | startflags flagset + { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) } + | startflags flagset '/' flagset + { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } + | startflags '/' flagset + { DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) } + | startflags YY_NUMBER + { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = FR_TCPFMAX;) } + | startflags '/' YY_NUMBER + { DOALL(fr->fr_tcpf = 0; fr->fr_tcpfm = $3;) } + | startflags YY_NUMBER '/' YY_NUMBER + { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } + | startflags flagset '/' YY_NUMBER + { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } + | startflags YY_NUMBER '/' flagset + { DOALL(fr->fr_tcpf = $2; fr->fr_tcpfm = $4;) } + ; + +startflags: + IPFY_FLAGS { if (frc->fr_type != FR_T_IPF) + yyerror("flags with non-ipf type rule"); + if (frc->fr_proto != IPPROTO_TCP) + yyerror("flags with non-TCP rule"); + } + ; + +flagset: + YY_STR { $$ = tcpflags($1); free($1); } + | YY_HEX { $$ = $1; } + ; + +srcobject: + { yyresetdict(); } fromport + | srcaddr srcport + | '!' srcaddr srcport + { DOALL(fr->fr_flags |= FR_NOTSRCIP;) } + ; + +srcaddr: + addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \ + bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \ + if (dynamic != -1) { \ + fr->fr_satype = ifpflag; \ + fr->fr_ipf->fri_sifpidx = dynamic; \ + } else if (pooled || hashed) \ + fr->fr_satype = FRI_LOOKUP;) + } + | lstart srcaddrlist lend + ; + +srcaddrlist: + addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_src, sizeof($1.a)); \ + bcopy(&($1.m), &fr->fr_mip.fi_src, sizeof($1.m)); \ + if (dynamic != -1) { \ + fr->fr_satype = ifpflag; \ + fr->fr_ipf->fri_sifpidx = dynamic; \ + } else if (pooled || hashed) \ + fr->fr_satype = FRI_LOOKUP;) + } + | srcaddrlist lmore addr + { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_src, sizeof($3.a)); \ + bcopy(&($3.m), &fr->fr_mip.fi_src, sizeof($3.m)); \ + if (dynamic != -1) { \ + fr->fr_satype = ifpflag; \ + fr->fr_ipf->fri_sifpidx = dynamic; \ + } else if (pooled || hashed) \ + fr->fr_satype = FRI_LOOKUP;) + } + ; + +srcport: + | portcomp + { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) } + | portrange + { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \ + fr->fr_stop = $1.p2;) } + | porteq lstart srcportlist lend + { yyresetdict(); } + ; + +fromport: + portcomp + { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1;) } + | portrange + { DOALL(fr->fr_scmp = $1.pc; fr->fr_sport = $1.p1; \ + fr->fr_stop = $1.p2;) } + | porteq lstart srcportlist lend + { yyresetdict(); } + ; + +srcportlist: + portnum { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $1;) } + | srcportlist lmore portnum + { DOREM(fr->fr_scmp = FR_EQUAL; fr->fr_sport = $3;) } + ; + +dstobject: + { yyresetdict(); } toport + | dstaddr dstport + | '!' dstaddr dstport + { DOALL(fr->fr_flags |= FR_NOTDSTIP;) } + ; + +dstaddr: + addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \ + bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \ + if (dynamic != -1) { \ + fr->fr_datype = ifpflag; \ + fr->fr_ipf->fri_difpidx = dynamic; \ + } else if (pooled || hashed) \ + fr->fr_datype = FRI_LOOKUP;) + } + | lstart dstaddrlist lend + ; + +dstaddrlist: + addr { DOREM(bcopy(&($1.a), &fr->fr_ip.fi_dst, sizeof($1.a)); \ + bcopy(&($1.m), &fr->fr_mip.fi_dst, sizeof($1.m)); \ + if (dynamic != -1) { \ + fr->fr_datype = ifpflag; \ + fr->fr_ipf->fri_difpidx = dynamic; \ + } else if (pooled || hashed) \ + fr->fr_datype = FRI_LOOKUP;) + } + | dstaddrlist lmore addr + { DOREM(bcopy(&($3.a), &fr->fr_ip.fi_dst, sizeof($3.a)); \ + bcopy(&($3.m), &fr->fr_mip.fi_dst, sizeof($3.m)); \ + if (dynamic != -1) { \ + fr->fr_datype = ifpflag; \ + fr->fr_ipf->fri_difpidx = dynamic; \ + } else if (pooled || hashed) \ + fr->fr_datype = FRI_LOOKUP;) + } + ; + + +dstport: + | portcomp + { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) } + | portrange + { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \ + fr->fr_dtop = $1.p2;) } + | porteq lstart dstportlist lend + { yyresetdict(); } + ; + +toport: + portcomp + { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1;) } + | portrange + { DOALL(fr->fr_dcmp = $1.pc; fr->fr_dport = $1.p1; \ + fr->fr_dtop = $1.p2;) } + | porteq lstart dstportlist lend + { yyresetdict(); } + ; + +dstportlist: + portnum { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $1;) } + | dstportlist lmore portnum + { DOREM(fr->fr_dcmp = FR_EQUAL; fr->fr_dport = $3;) } + ; + +addr: pool '/' YY_NUMBER { pooled = 1; + yyexpectaddr = 0; + $$.a.iplookuptype = IPLT_POOL; + $$.a.iplookupnum = $3; } + | pool '=' '(' poollist ')' { pooled = 1; + yyexpectaddr = 0; + $$.a.iplookuptype = IPLT_POOL; + $$.a.iplookupnum = makepool($4); } + | hash '/' YY_NUMBER { hashed = 1; + yyexpectaddr = 0; + $$.a.iplookuptype = IPLT_HASH; + $$.a.iplookupnum = $3; } + | hash '=' '(' addrlist ')' { hashed = 1; + yyexpectaddr = 0; + $$.a.iplookuptype = IPLT_HASH; + $$.a.iplookupnum = makehash($4); } + | ipaddr { bcopy(&$1, &$$, sizeof($$)); + yyexpectaddr = 0; } + ; + +ipaddr: IPFY_ANY { bzero(&($$), sizeof($$)); + yyresetdict(); + yyexpectaddr = 0; } + | hostname { $$.a.in4 = $1; + $$.m.in4_addr = 0xffffffff; + yyexpectaddr = 0; } + | hostname { yyresetdict(); + $$.a.in4_addr = $1.s_addr; } + maskspace { yysetdict(maskwords); } + ipv4mask { $$.m.in4_addr = $5.s_addr; + $$.a.in4_addr &= $5.s_addr; + yyresetdict(); + yyexpectaddr = 0; } + | YY_IPV6 { bcopy(&$1, &$$.a, sizeof($$.a)); + fill6bits(128, (u_32_t *)&$$.m); + yyresetdict(); + yyexpectaddr = 0; } + | YY_IPV6 { yyresetdict(); + bcopy(&$1, &$$.a, sizeof($$.a)); } + maskspace { yysetdict(maskwords); } + ipv6mask { bcopy(&$5, &$$.m, sizeof($$.m)); + yyresetdict(); + yyexpectaddr = 0; } + ; +maskspace: + '/' + | IPFY_MASK + ; + +ipv4mask: + ipv4 { $$ = $1; } + | YY_HEX { $$.s_addr = htonl($1); } + | YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$); } + | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) { + $$.s_addr = 0; + ifpflag = FRI_BROADCAST; + } else + YYERROR; + } + | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) { + $$.s_addr = 0; + ifpflag = FRI_NETWORK; + } else + YYERROR; + } + | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) { + $$.s_addr = 0; + ifpflag = FRI_NETMASKED; + } else + YYERROR; + } + | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) { + $$.s_addr = 0; + ifpflag = FRI_PEERADDR; + } else + YYERROR; + } + ; + +ipv6mask: + YY_NUMBER { ntomask(6, $1, $$.i6); } + | IPFY_BROADCAST { if (ifpflag == FRI_DYNAMIC) { + bzero(&$$, sizeof($$)); + ifpflag = FRI_BROADCAST; + } else + YYERROR; + } + | IPFY_NETWORK { if (ifpflag == FRI_DYNAMIC) { + bzero(&$$, sizeof($$)); + ifpflag = FRI_BROADCAST; + } else + YYERROR; + } + | IPFY_NETMASKED { if (ifpflag == FRI_DYNAMIC) { + bzero(&$$, sizeof($$)); + ifpflag = FRI_BROADCAST; + } else + YYERROR; + } + | IPFY_PEER { if (ifpflag == FRI_DYNAMIC) { + bzero(&$$, sizeof($$)); + ifpflag = FRI_BROADCAST; + } else + YYERROR; + } + ; + +hostname: + ipv4 { $$ = $1; } + | YY_NUMBER { $$.s_addr = $1; } + | YY_HEX { $$.s_addr = $1; } + | YY_STR { $$.s_addr = lookuphost($1); + free($1); + } + ; + +addrlist: + ipaddr { $$ = newalist(NULL); + bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a)); + bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); } + | addrlist ',' ipaddr + { $$ = newalist($1); + bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a)); + bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); } + ; + +pool: IPFY_POOL { yyexpectaddr = 0; yycont = NULL; yyresetdict(); } + ; + +hash: IPFY_HASH { yyexpectaddr = 0; yycont = NULL; yyresetdict(); } + ; + +poollist: + ipaddr { $$ = newalist(NULL); + bcopy(&($1.a), &($$->al_i6addr), sizeof($1.a)); + bcopy(&($1.m), &($$->al_i6mask), sizeof($1.m)); } + | '!' ipaddr { $$ = newalist(NULL); + $$->al_not = 1; + bcopy(&($2.a), &($$->al_i6addr), sizeof($2.a)); + bcopy(&($2.m), &($$->al_i6mask), sizeof($2.m)); } + | poollist ',' ipaddr + { $$ = newalist($1); + bcopy(&($3.a), &($$->al_i6addr), sizeof($3.a)); + bcopy(&($3.m), &($$->al_i6mask), sizeof($3.m)); } + | poollist ',' '!' ipaddr + { $$ = newalist($1); + $$->al_not = 1; + bcopy(&($4.a), &($$->al_i6addr), sizeof($4.a)); + bcopy(&($4.m), &($$->al_i6mask), sizeof($4.m)); } + ; + +port: IPFY_PORT { yyexpectaddr = 0; + yycont = NULL; + } + ; + +portc: port compare { $$ = $2; + yysetdict(NULL); } + | porteq { $$ = $1; } + ; + +porteq: port '=' { $$ = FR_EQUAL; + yysetdict(NULL); } + ; + +portr: IPFY_PORT { yyexpectaddr = 0; + yycont = NULL; + yysetdict(NULL); } + ; + +portcomp: + portc portnum { $$.pc = $1; + $$.p1 = $2; + yyresetdict(); } + ; + +portrange: + portr portnum range portnum { $$.p1 = $2; + $$.pc = $3; + $$.p2 = $4; + yyresetdict(); } + ; + +icmp: | itype icode + ; + +itype: seticmptype icmptype + { DOALL(fr->fr_icmp = htons($2 << 8); fr->fr_icmpm = htons(0xff00);); + yyresetdict(); + } + | seticmptype lstart typelist lend { yyresetdict(); } + ; + +seticmptype: + IPFY_ICMPTYPE { setipftype(); + yysetdict(icmptypewords); } + ; + +icode: | seticmpcode icmpcode + { DOALL(fr->fr_icmp |= htons($2); fr->fr_icmpm |= htons(0xff);); + yyresetdict(); + } + | seticmpcode lstart codelist lend { yyresetdict(); } + ; + +seticmpcode: + IPFY_ICMPCODE { yysetdict(icmpcodewords); } + ; + +typelist: + icmptype + { DOREM(fr->fr_icmp = htons($1 << 8); fr->fr_icmpm = htons(0xff00);) } + | typelist lmore icmptype + { DOREM(fr->fr_icmp = htons($3 << 8); fr->fr_icmpm = htons(0xff00);) } + ; + +codelist: + icmpcode + { DOREM(fr->fr_icmp |= htons($1); fr->fr_icmpm |= htons(0xff);) } + | codelist lmore icmpcode + { DOREM(fr->fr_icmp |= htons($3); fr->fr_icmpm |= htons(0xff);) } + ; + +age: | IPFY_AGE YY_NUMBER { DOALL(fr->fr_age[0] = $2; \ + fr->fr_age[1] = $2;) } + | IPFY_AGE YY_NUMBER '/' YY_NUMBER + { DOALL(fr->fr_age[0] = $2; \ + fr->fr_age[1] = $4;) } + ; + +keep: | IPFY_KEEP keepstate keep + | IPFY_KEEP keepfrag keep + ; + +keepstate: + IPFY_STATE stateoptlist { DOALL(fr->fr_flags |= FR_KEEPSTATE;)} + ; + +keepfrag: + IPFY_FRAGS fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) } + | IPFY_FRAG fragoptlist { DOALL(fr->fr_flags |= FR_KEEPFRAG;) } + ; + +fragoptlist: + | '(' fragopts ')' + ; + +fragopts: + fragopt lanother fragopts + | fragopt + ; + +fragopt: + IPFY_STRICT { DOALL(fr->fr_flags |= FR_FRSTRICT;) } + ; + +stateoptlist: + | '(' stateopts ')' + ; + +stateopts: + stateopt lanother stateopts + | stateopt + ; + +stateopt: + IPFY_LIMIT YY_NUMBER { DOALL(fr->fr_statemax = $2;) } + | IPFY_STRICT { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ + YYERROR; \ + } else \ + fr->fr_flags |= FR_STSTRICT;) + } + | IPFY_NEWISN { DOALL(if (fr->fr_proto != IPPROTO_TCP) { \ + YYERROR; \ + } else \ + fr->fr_flags |= FR_NEWISN;) + } + | IPFY_NOICMPERR { DOALL(fr->fr_flags |= FR_NOICMPERR;) } + + | IPFY_SYNC { DOALL(fr->fr_flags |= FR_STATESYNC;) } + ; + +portnum: + servicename { if (getport(frc, $1, &($$)) == -1) + yyerror("service unknown"); + $$ = ntohs($$); + free($1); + } + | YY_NUMBER { if ($1 > 65535) /* Unsigned */ + yyerror("invalid port number"); + else + $$ = $1; + } + ; + +withlist: + withopt + | withlist withopt + | withlist ',' withopt + ; + +withopt: + opttype { DOALL(fr->fr_flx |= $1; fr->fr_mflx |= $1;) } + | notwith opttype + { DOALL(fr->fr_mflx |= $2;) } + | ipopt ipopts { yyresetdict(); } + | notwith ipopt ipopts { yyresetdict(); } + | startv6hdrs ipv6hdrs { yyresetdict(); } + ; + +ipopt: IPFY_OPT { yysetdict(ipv4optwords); } + ; + +startv6hdrs: + IPF6_V6HDRS { if (use_inet6 == 0) + yyerror("only available with IPv6"); + yysetdict(ipv6optwords); + } + ; + +notwith: + IPFY_NOT { nowith = 1; } + | IPFY_NO { nowith = 1; } + ; + +opttype: + IPFY_IPOPTS { $$ = FI_OPTIONS; } + | IPFY_SHORT { $$ = FI_SHORT; } + | IPFY_NAT { $$ = FI_NATED; } + | IPFY_BAD { $$ = FI_BAD; } + | IPFY_BADNAT { $$ = FI_BADNAT; } + | IPFY_BADSRC { $$ = FI_BADSRC; } + | IPFY_LOWTTL { $$ = FI_LOWTTL; } + | IPFY_FRAG { $$ = FI_FRAG; } + | IPFY_FRAGBODY { $$ = FI_FRAGBODY; } + | IPFY_FRAGS { $$ = FI_FRAG; } + | IPFY_MBCAST { $$ = FI_MBCAST; } + | IPFY_MULTICAST { $$ = FI_MULTICAST; } + | IPFY_BROADCAST { $$ = FI_BROADCAST; } + | IPFY_STATE { $$ = FI_STATE; } + | IPFY_OOW { $$ = FI_OOW; } + ; + +ipopts: optlist { DOALL(fr->fr_mip.fi_optmsk |= $1; + if (!nowith) + fr->fr_ip.fi_optmsk |= $1;) + } + ; + +optlist: + opt { $$ |= $1; } + | optlist ',' opt { $$ |= $1 | $3; } + ; + +ipv6hdrs: + ipv6hdrlist { DOALL(fr->fr_mip.fi_optmsk |= $1; + if (!nowith) + fr->fr_ip.fi_optmsk |= $1;) + } + ; + +ipv6hdrlist: + ipv6hdr { $$ |= $1; } + | ipv6hdrlist ',' ipv6hdr { $$ |= $1 | $3; } + ; + +secname: + seclevel { $$ |= $1; } + | secname ',' seclevel { $$ |= $1 | $3; } + ; + +seclevel: + IPFY_SEC_UNC { $$ = secbit(IPSO_CLASS_UNCL); } + | IPFY_SEC_CONF { $$ = secbit(IPSO_CLASS_CONF); } + | IPFY_SEC_RSV1 { $$ = secbit(IPSO_CLASS_RES1); } + | IPFY_SEC_RSV2 { $$ = secbit(IPSO_CLASS_RES2); } + | IPFY_SEC_RSV3 { $$ = secbit(IPSO_CLASS_RES3); } + | IPFY_SEC_RSV4 { $$ = secbit(IPSO_CLASS_RES4); } + | IPFY_SEC_SEC { $$ = secbit(IPSO_CLASS_SECR); } + | IPFY_SEC_TS { $$ = secbit(IPSO_CLASS_TOPS); } + ; + +icmptype: + YY_NUMBER { $$ = $1; } + | IPFY_ICMPT_UNR { $$ = ICMP_UNREACH; } + | IPFY_ICMPT_ECHO { $$ = ICMP_ECHO; } + | IPFY_ICMPT_ECHOR { $$ = ICMP_ECHOREPLY; } + | IPFY_ICMPT_SQUENCH { $$ = ICMP_SOURCEQUENCH; } + | IPFY_ICMPT_REDIR { $$ = ICMP_REDIRECT; } + | IPFY_ICMPT_TIMEX { $$ = ICMP_TIMXCEED; } + | IPFY_ICMPT_PARAMP { $$ = ICMP_PARAMPROB; } + | IPFY_ICMPT_TIMEST { $$ = ICMP_TSTAMP; } + | IPFY_ICMPT_TIMESTREP { $$ = ICMP_TSTAMPREPLY; } + | IPFY_ICMPT_INFOREQ { $$ = ICMP_IREQ; } + | IPFY_ICMPT_INFOREP { $$ = ICMP_IREQREPLY; } + | IPFY_ICMPT_MASKREQ { $$ = ICMP_MASKREQ; } + | IPFY_ICMPT_MASKREP { $$ = ICMP_MASKREPLY; } + | IPFY_ICMPT_ROUTERAD { $$ = ICMP_ROUTERADVERT; } + | IPFY_ICMPT_ROUTERSOL { $$ = ICMP_ROUTERSOLICIT; } + ; + +icmpcode: + YY_NUMBER { $$ = $1; } + | IPFY_ICMPC_NETUNR { $$ = ICMP_UNREACH_NET; } + | IPFY_ICMPC_HSTUNR { $$ = ICMP_UNREACH_HOST; } + | IPFY_ICMPC_PROUNR { $$ = ICMP_UNREACH_PROTOCOL; } + | IPFY_ICMPC_PORUNR { $$ = ICMP_UNREACH_PORT; } + | IPFY_ICMPC_NEEDF { $$ = ICMP_UNREACH_NEEDFRAG; } + | IPFY_ICMPC_SRCFAIL { $$ = ICMP_UNREACH_SRCFAIL; } + | IPFY_ICMPC_NETUNK { $$ = ICMP_UNREACH_NET_UNKNOWN; } + | IPFY_ICMPC_HSTUNK { $$ = ICMP_UNREACH_HOST_UNKNOWN; } + | IPFY_ICMPC_ISOLATE { $$ = ICMP_UNREACH_ISOLATED; } + | IPFY_ICMPC_NETPRO { $$ = ICMP_UNREACH_NET_PROHIB; } + | IPFY_ICMPC_HSTPRO { $$ = ICMP_UNREACH_HOST_PROHIB; } + | IPFY_ICMPC_NETTOS { $$ = ICMP_UNREACH_TOSNET; } + | IPFY_ICMPC_HSTTOS { $$ = ICMP_UNREACH_TOSHOST; } + | IPFY_ICMPC_FLTPRO { $$ = ICMP_UNREACH_ADMIN_PROHIBIT; } + | IPFY_ICMPC_HSTPRE { $$ = 14; } + | IPFY_ICMPC_CUTPRE { $$ = 15; } + ; + +opt: + IPFY_IPOPT_NOP { $$ = getoptbyvalue(IPOPT_NOP); } + | IPFY_IPOPT_RR { $$ = getoptbyvalue(IPOPT_RR); } + | IPFY_IPOPT_ZSU { $$ = getoptbyvalue(IPOPT_ZSU); } + | IPFY_IPOPT_MTUP { $$ = getoptbyvalue(IPOPT_MTUP); } + | IPFY_IPOPT_MTUR { $$ = getoptbyvalue(IPOPT_MTUR); } + | IPFY_IPOPT_ENCODE { $$ = getoptbyvalue(IPOPT_ENCODE); } + | IPFY_IPOPT_TS { $$ = getoptbyvalue(IPOPT_TS); } + | IPFY_IPOPT_TR { $$ = getoptbyvalue(IPOPT_TR); } + | IPFY_IPOPT_SEC { $$ = getoptbyvalue(IPOPT_SECURITY); } + | IPFY_IPOPT_LSRR { $$ = getoptbyvalue(IPOPT_LSRR); } + | IPFY_IPOPT_ESEC { $$ = getoptbyvalue(IPOPT_E_SEC); } + | IPFY_IPOPT_CIPSO { $$ = getoptbyvalue(IPOPT_CIPSO); } + | IPFY_IPOPT_SATID { $$ = getoptbyvalue(IPOPT_SATID); } + | IPFY_IPOPT_SSRR { $$ = getoptbyvalue(IPOPT_SSRR); } + | IPFY_IPOPT_ADDEXT { $$ = getoptbyvalue(IPOPT_ADDEXT); } + | IPFY_IPOPT_VISA { $$ = getoptbyvalue(IPOPT_VISA); } + | IPFY_IPOPT_IMITD { $$ = getoptbyvalue(IPOPT_IMITD); } + | IPFY_IPOPT_EIP { $$ = getoptbyvalue(IPOPT_EIP); } + | IPFY_IPOPT_FINN { $$ = getoptbyvalue(IPOPT_FINN); } + | IPFY_IPOPT_DPS { $$ = getoptbyvalue(IPOPT_DPS); } + | IPFY_IPOPT_SDB { $$ = getoptbyvalue(IPOPT_SDB); } + | IPFY_IPOPT_NSAPA { $$ = getoptbyvalue(IPOPT_NSAPA); } + | IPFY_IPOPT_RTRALRT { $$ = getoptbyvalue(IPOPT_RTRALRT); } + | IPFY_IPOPT_UMP { $$ = getoptbyvalue(IPOPT_UMP); } + | setsecclass secname + { DOALL(fr->fr_mip.fi_secmsk |= $2; + if (!nowith) + fr->fr_ip.fi_secmsk |= $2;) + $$ = 0; + yyresetdict(); + } + ; + +setsecclass: + IPFY_SECCLASS { yysetdict(ipv4secwords); } + ; + +ipv6hdr: + IPFY_AH { $$ = getv6optbyvalue(IPPROTO_AH); } + | IPFY_IPV6OPT_DSTOPTS { $$ = getv6optbyvalue(IPPROTO_DSTOPTS); } + | IPFY_ESP { $$ = getv6optbyvalue(IPPROTO_ESP); } + | IPFY_IPV6OPT_HOPOPTS { $$ = getv6optbyvalue(IPPROTO_HOPOPTS); } + | IPFY_IPV6OPT_IPV6 { $$ = getv6optbyvalue(IPPROTO_IPV6); } + | IPFY_IPV6OPT_NONE { $$ = getv6optbyvalue(IPPROTO_NONE); } + | IPFY_IPV6OPT_ROUTING { $$ = getv6optbyvalue(IPPROTO_ROUTING); } + | IPFY_FRAG { $$ = getv6optbyvalue(IPPROTO_FRAGMENT); } + ; + +level: IPFY_LEVEL { setsyslog(); } + ; + +loglevel: + priority { fr->fr_loglevel = LOG_LOCAL0|$1; } + | facility '.' priority { fr->fr_loglevel = $1 | $3; } + ; + +facility: + IPFY_FAC_KERN { $$ = LOG_KERN; } + | IPFY_FAC_USER { $$ = LOG_USER; } + | IPFY_FAC_MAIL { $$ = LOG_MAIL; } + | IPFY_FAC_DAEMON { $$ = LOG_DAEMON; } + | IPFY_FAC_AUTH { $$ = LOG_AUTH; } + | IPFY_FAC_SYSLOG { $$ = LOG_SYSLOG; } + | IPFY_FAC_LPR { $$ = LOG_LPR; } + | IPFY_FAC_NEWS { $$ = LOG_NEWS; } + | IPFY_FAC_UUCP { $$ = LOG_UUCP; } + | IPFY_FAC_CRON { $$ = LOG_CRON; } + | IPFY_FAC_FTP { $$ = LOG_FTP; } + | IPFY_FAC_AUTHPRIV { $$ = LOG_AUTHPRIV; } + | IPFY_FAC_AUDIT { $$ = LOG_AUDIT; } + | IPFY_FAC_LFMT { $$ = LOG_LFMT; } + | IPFY_FAC_LOCAL0 { $$ = LOG_LOCAL0; } + | IPFY_FAC_LOCAL1 { $$ = LOG_LOCAL1; } + | IPFY_FAC_LOCAL2 { $$ = LOG_LOCAL2; } + | IPFY_FAC_LOCAL3 { $$ = LOG_LOCAL3; } + | IPFY_FAC_LOCAL4 { $$ = LOG_LOCAL4; } + | IPFY_FAC_LOCAL5 { $$ = LOG_LOCAL5; } + | IPFY_FAC_LOCAL6 { $$ = LOG_LOCAL6; } + | IPFY_FAC_LOCAL7 { $$ = LOG_LOCAL7; } + | IPFY_FAC_SECURITY { $$ = LOG_SECURITY; } + ; + +priority: + IPFY_PRI_EMERG { $$ = LOG_EMERG; } + | IPFY_PRI_ALERT { $$ = LOG_ALERT; } + | IPFY_PRI_CRIT { $$ = LOG_CRIT; } + | IPFY_PRI_ERR { $$ = LOG_ERR; } + | IPFY_PRI_WARN { $$ = LOG_WARNING; } + | IPFY_PRI_NOTICE { $$ = LOG_NOTICE; } + | IPFY_PRI_INFO { $$ = LOG_INFO; } + | IPFY_PRI_DEBUG { $$ = LOG_DEBUG; } + ; + +compare: + YY_CMP_EQ { $$ = FR_EQUAL; } + | YY_CMP_NE { $$ = FR_NEQUAL; } + | YY_CMP_LT { $$ = FR_LESST; } + | YY_CMP_LE { $$ = FR_LESSTE; } + | YY_CMP_GT { $$ = FR_GREATERT; } + | YY_CMP_GE { $$ = FR_GREATERTE; } + ; + +range: YY_RANGE_IN { $$ = FR_INRANGE; } + | YY_RANGE_OUT { $$ = FR_OUTRANGE; } + | ':' { $$ = FR_INCRANGE; } + ; + +servicename: + YY_STR { $$ = $1; } + ; + +interfacename: YY_STR { $$ = $1; } + | YY_STR ':' YY_NUMBER + { $$ = $1; + fprintf(stderr, "%d: Logical interface %s:%d unsupported, " + "use the physical interface %s instead.\n", + yylineNum, $1, $3, $1); + } + ; + +name: YY_STR { $$ = $1; } + ; + +ipv4_16: + YY_NUMBER '.' YY_NUMBER + { if ($1 > 255 || $3 > 255) { + yyerror("Invalid octet string for IP address"); + return 0; + } + $$.s_addr = ($1 << 24) | ($3 << 16); + $$.s_addr = htonl($$.s_addr); + } + ; + +ipv4_24: + ipv4_16 '.' YY_NUMBER + { if ($3 > 255) { + yyerror("Invalid octet string for IP address"); + return 0; + } + $$.s_addr |= htonl($3 << 8); + } + ; + +ipv4: ipv4_24 '.' YY_NUMBER + { if ($3 > 255) { + yyerror("Invalid octet string for IP address"); + return 0; + } + $$.s_addr |= htonl($3); + } + | ipv4_24 + | ipv4_16 + ; + +%% + + +static struct wordtab ipfwords[95] = { + { "age", IPFY_AGE }, + { "ah", IPFY_AH }, + { "all", IPFY_ALL }, + { "and", IPFY_AND }, + { "auth", IPFY_AUTH }, + { "bad", IPFY_BAD }, + { "bad-nat", IPFY_BADNAT }, + { "bad-src", IPFY_BADSRC }, + { "bcast", IPFY_BROADCAST }, + { "block", IPFY_BLOCK }, + { "body", IPFY_BODY }, + { "bpf-v4", IPFY_BPFV4 }, +#ifdef USE_INET6 + { "bpf-v6", IPFY_BPFV6 }, +#endif + { "call", IPFY_CALL }, + { "code", IPFY_ICMPCODE }, + { "count", IPFY_COUNT }, + { "dup-to", IPFY_DUPTO }, + { "eq", YY_CMP_EQ }, + { "esp", IPFY_ESP }, + { "fastroute", IPFY_FROUTE }, + { "first", IPFY_FIRST }, + { "flags", IPFY_FLAGS }, + { "frag", IPFY_FRAG }, + { "frag-body", IPFY_FRAGBODY }, + { "frags", IPFY_FRAGS }, + { "from", IPFY_FROM }, + { "ge", YY_CMP_GE }, + { "group", IPFY_GROUP }, + { "gt", YY_CMP_GT }, + { "head", IPFY_HEAD }, + { "icmp", IPFY_ICMP }, + { "icmp-type", IPFY_ICMPTYPE }, + { "in", IPFY_IN }, + { "in-via", IPFY_INVIA }, + { "ipopt", IPFY_IPOPTS }, + { "ipopts", IPFY_IPOPTS }, + { "keep", IPFY_KEEP }, + { "le", YY_CMP_LE }, + { "level", IPFY_LEVEL }, + { "limit", IPFY_LIMIT }, + { "log", IPFY_LOG }, + { "lowttl", IPFY_LOWTTL }, + { "lt", YY_CMP_LT }, + { "mask", IPFY_MASK }, + { "match-tag", IPFY_MATCHTAG }, + { "mbcast", IPFY_MBCAST }, + { "multicast", IPFY_MULTICAST }, + { "nat", IPFY_NAT }, + { "ne", YY_CMP_NE }, + { "net", IPFY_NETWORK }, + { "newisn", IPFY_NEWISN }, + { "no", IPFY_NO }, + { "no-icmp-err", IPFY_NOICMPERR }, + { "now", IPFY_NOW }, + { "not", IPFY_NOT }, + { "oow", IPFY_OOW }, + { "on", IPFY_ON }, + { "opt", IPFY_OPT }, + { "or-block", IPFY_ORBLOCK }, + { "out", IPFY_OUT }, + { "out-via", IPFY_OUTVIA }, + { "pass", IPFY_PASS }, + { "port", IPFY_PORT }, + { "pps", IPFY_PPS }, + { "preauth", IPFY_PREAUTH }, + { "proto", IPFY_PROTO }, + { "quick", IPFY_QUICK }, + { "reply-to", IPFY_REPLY_TO }, + { "return-icmp", IPFY_RETICMP }, + { "return-icmp-as-dest", IPFY_RETICMPASDST }, + { "return-rst", IPFY_RETRST }, + { "route-to", IPFY_ROUTETO }, + { "sec-class", IPFY_SECCLASS }, + { "set-tag", IPFY_SETTAG }, + { "skip", IPFY_SKIP }, + { "short", IPFY_SHORT }, + { "state", IPFY_STATE }, + { "state-age", IPFY_AGE }, + { "strict", IPFY_STRICT }, + { "sync", IPFY_SYNC }, + { "tcp", IPFY_TCP }, + { "tcp-udp", IPFY_TCPUDP }, + { "tos", IPFY_TOS }, + { "to", IPFY_TO }, + { "ttl", IPFY_TTL }, + { "udp", IPFY_UDP }, + { "v6hdrs", IPF6_V6HDRS }, + { "with", IPFY_WITH }, + { NULL, 0 } +}; + +static struct wordtab addrwords[4] = { + { "any", IPFY_ANY }, + { "hash", IPFY_HASH }, + { "pool", IPFY_POOL }, + { NULL, 0 } +}; + +static struct wordtab maskwords[5] = { + { "broadcast", IPFY_BROADCAST }, + { "netmasked", IPFY_NETMASKED }, + { "network", IPFY_NETWORK }, + { "peer", IPFY_PEER }, + { NULL, 0 } +}; + +static struct wordtab icmptypewords[16] = { + { "echo", IPFY_ICMPT_ECHO }, + { "echorep", IPFY_ICMPT_ECHOR }, + { "inforeq", IPFY_ICMPT_INFOREQ }, + { "inforep", IPFY_ICMPT_INFOREP }, + { "maskrep", IPFY_ICMPT_MASKREP }, + { "maskreq", IPFY_ICMPT_MASKREQ }, + { "paramprob", IPFY_ICMPT_PARAMP }, + { "redir", IPFY_ICMPT_REDIR }, + { "unreach", IPFY_ICMPT_UNR }, + { "routerad", IPFY_ICMPT_ROUTERAD }, + { "routersol", IPFY_ICMPT_ROUTERSOL }, + { "squench", IPFY_ICMPT_SQUENCH }, + { "timest", IPFY_ICMPT_TIMEST }, + { "timestrep", IPFY_ICMPT_TIMESTREP }, + { "timex", IPFY_ICMPT_TIMEX }, + { NULL, 0 }, +}; + +static struct wordtab icmpcodewords[17] = { + { "cutoff-preced", IPFY_ICMPC_CUTPRE }, + { "filter-prohib", IPFY_ICMPC_FLTPRO }, + { "isolate", IPFY_ICMPC_ISOLATE }, + { "needfrag", IPFY_ICMPC_NEEDF }, + { "net-prohib", IPFY_ICMPC_NETPRO }, + { "net-tos", IPFY_ICMPC_NETTOS }, + { "host-preced", IPFY_ICMPC_HSTPRE }, + { "host-prohib", IPFY_ICMPC_HSTPRO }, + { "host-tos", IPFY_ICMPC_HSTTOS }, + { "host-unk", IPFY_ICMPC_HSTUNK }, + { "host-unr", IPFY_ICMPC_HSTUNR }, + { "net-unk", IPFY_ICMPC_NETUNK }, + { "net-unr", IPFY_ICMPC_NETUNR }, + { "port-unr", IPFY_ICMPC_PORUNR }, + { "proto-unr", IPFY_ICMPC_PROUNR }, + { "srcfail", IPFY_ICMPC_SRCFAIL }, + { NULL, 0 }, +}; + +static struct wordtab ipv4optwords[25] = { + { "addext", IPFY_IPOPT_ADDEXT }, + { "cipso", IPFY_IPOPT_CIPSO }, + { "dps", IPFY_IPOPT_DPS }, + { "e-sec", IPFY_IPOPT_ESEC }, + { "eip", IPFY_IPOPT_EIP }, + { "encode", IPFY_IPOPT_ENCODE }, + { "finn", IPFY_IPOPT_FINN }, + { "imitd", IPFY_IPOPT_IMITD }, + { "lsrr", IPFY_IPOPT_LSRR }, + { "mtup", IPFY_IPOPT_MTUP }, + { "mtur", IPFY_IPOPT_MTUR }, + { "nop", IPFY_IPOPT_NOP }, + { "nsapa", IPFY_IPOPT_NSAPA }, + { "rr", IPFY_IPOPT_RR }, + { "rtralrt", IPFY_IPOPT_RTRALRT }, + { "satid", IPFY_IPOPT_SATID }, + { "sdb", IPFY_IPOPT_SDB }, + { "sec", IPFY_IPOPT_SEC }, + { "ssrr", IPFY_IPOPT_SSRR }, + { "tr", IPFY_IPOPT_TR }, + { "ts", IPFY_IPOPT_TS }, + { "ump", IPFY_IPOPT_UMP }, + { "visa", IPFY_IPOPT_VISA }, + { "zsu", IPFY_IPOPT_ZSU }, + { NULL, 0 }, +}; + +static struct wordtab ipv4secwords[9] = { + { "confid", IPFY_SEC_CONF }, + { "reserv-1", IPFY_SEC_RSV1 }, + { "reserv-2", IPFY_SEC_RSV2 }, + { "reserv-3", IPFY_SEC_RSV3 }, + { "reserv-4", IPFY_SEC_RSV4 }, + { "secret", IPFY_SEC_SEC }, + { "topsecret", IPFY_SEC_TS }, + { "unclass", IPFY_SEC_UNC }, + { NULL, 0 }, +}; + +static struct wordtab ipv6optwords[8] = { + { "dstopts", IPFY_IPV6OPT_DSTOPTS }, + { "esp", IPFY_ESP }, + { "frag", IPFY_FRAG }, + { "hopopts", IPFY_IPV6OPT_HOPOPTS }, + { "ipv6", IPFY_IPV6OPT_IPV6 }, + { "none", IPFY_IPV6OPT_NONE }, + { "routing", IPFY_IPV6OPT_ROUTING }, + { NULL, 0 }, +}; + +static struct wordtab logwords[33] = { + { "kern", IPFY_FAC_KERN }, + { "user", IPFY_FAC_USER }, + { "mail", IPFY_FAC_MAIL }, + { "daemon", IPFY_FAC_DAEMON }, + { "auth", IPFY_FAC_AUTH }, + { "syslog", IPFY_FAC_SYSLOG }, + { "lpr", IPFY_FAC_LPR }, + { "news", IPFY_FAC_NEWS }, + { "uucp", IPFY_FAC_UUCP }, + { "cron", IPFY_FAC_CRON }, + { "ftp", IPFY_FAC_FTP }, + { "authpriv", IPFY_FAC_AUTHPRIV }, + { "audit", IPFY_FAC_AUDIT }, + { "logalert", IPFY_FAC_LFMT }, + { "console", IPFY_FAC_CONSOLE }, + { "security", IPFY_FAC_SECURITY }, + { "local0", IPFY_FAC_LOCAL0 }, + { "local1", IPFY_FAC_LOCAL1 }, + { "local2", IPFY_FAC_LOCAL2 }, + { "local3", IPFY_FAC_LOCAL3 }, + { "local4", IPFY_FAC_LOCAL4 }, + { "local5", IPFY_FAC_LOCAL5 }, + { "local6", IPFY_FAC_LOCAL6 }, + { "local7", IPFY_FAC_LOCAL7 }, + { "emerg", IPFY_PRI_EMERG }, + { "alert", IPFY_PRI_ALERT }, + { "crit", IPFY_PRI_CRIT }, + { "err", IPFY_PRI_ERR }, + { "warn", IPFY_PRI_WARN }, + { "notice", IPFY_PRI_NOTICE }, + { "info", IPFY_PRI_INFO }, + { "debug", IPFY_PRI_DEBUG }, + { NULL, 0 }, +}; + + + + +int ipf_parsefile(fd, addfunc, iocfuncs, filename) +int fd; +addfunc_t addfunc; +ioctlfunc_t *iocfuncs; +char *filename; +{ + FILE *fp = NULL; + char *s; + + yylineNum = 1; + yysettab(ipfwords); + + s = getenv("YYDEBUG"); + if (s != NULL) + yydebug = atoi(s); + else + yydebug = 0; + + if (strcmp(filename, "-")) { + fp = fopen(filename, "r"); + if (fp == NULL) { + fprintf(stderr, "fopen(%s) failed: %s\n", filename, + STRERROR(errno)); + return -1; + } + } else + fp = stdin; + + while (ipf_parsesome(fd, addfunc, iocfuncs, fp) == 1) + ; + if (fp != NULL) + fclose(fp); + return 0; +} + + +int ipf_parsesome(fd, addfunc, iocfuncs, fp) +int fd; +addfunc_t addfunc; +ioctlfunc_t *iocfuncs; +FILE *fp; +{ + char *s; + int i; + + ipffd = fd; + for (i = 0; i <= IPL_LOGMAX; i++) + ipfioctl[i] = iocfuncs[i]; + ipfaddfunc = addfunc; + + if (feof(fp)) + return 0; + i = fgetc(fp); + if (i == EOF) + return 0; + if (ungetc(i, fp) == 0) + return 0; + if (feof(fp)) + return 0; + s = getenv("YYDEBUG"); + if (s != NULL) + yydebug = atoi(s); + else + yydebug = 0; + + yyin = fp; + yyparse(); + return 1; +} + + +static void newrule() +{ + frentry_t *frn; + + frn = (frentry_t *)calloc(1, sizeof(frentry_t)); + for (fr = frtop; fr != NULL && fr->fr_next != NULL; fr = fr->fr_next) + ; + if (fr != NULL) + fr->fr_next = frn; + if (frtop == NULL) + frtop = frn; + fr = frn; + frc = frn; + fr->fr_loglevel = 0xffff; + fr->fr_isc = (void *)-1; + fr->fr_logtag = FR_NOLOGTAG; + fr->fr_type = FR_T_NONE; + if (use_inet6 != 0) + fr->fr_v = 6; + else + fr->fr_v = 4; + + nrules = 1; +} + + +static void setipftype() +{ + for (fr = frc; fr != NULL; fr = fr->fr_next) { + if (fr->fr_type == FR_T_NONE) { + fr->fr_type = FR_T_IPF; + fr->fr_data = (void *)calloc(sizeof(fripf_t), 1); + fr->fr_dsize = sizeof(fripf_t); + fr->fr_ip.fi_v = frc->fr_v; + fr->fr_mip.fi_v = 0xf; + fr->fr_ipf->fri_sifpidx = -1; + fr->fr_ipf->fri_difpidx = -1; + } + if (fr->fr_type != FR_T_IPF) { + fprintf(stderr, "IPF Type not set\n"); + } + } +} + + +static frentry_t *addrule() +{ + frentry_t *f, *f1, *f2; + int count; + + for (f2 = frc; f2->fr_next != NULL; f2 = f2->fr_next) + ; + + count = nrules; + if (count == 0) { + f = (frentry_t *)calloc(sizeof(*f), 1); + added++; + f2->fr_next = f; + bcopy(f2, f, sizeof(*f)); + if (f2->fr_caddr != NULL) { + f->fr_caddr = malloc(f->fr_dsize); + bcopy(f2->fr_caddr, f->fr_caddr, f->fr_dsize); + } + f->fr_next = NULL; + return f; + } + f = f2; + for (f1 = frc; count > 0; count--, f1 = f1->fr_next) { + f->fr_next = (frentry_t *)calloc(sizeof(*f), 1); + added++; + f = f->fr_next; + bcopy(f1, f, sizeof(*f)); + f->fr_next = NULL; + if (f->fr_caddr != NULL) { + f->fr_caddr = malloc(f->fr_dsize); + bcopy(f1->fr_caddr, f->fr_caddr, f->fr_dsize); + } + } + + return f2->fr_next; +} + + +static u_32_t lookuphost(name) +char *name; +{ + u_32_t addr; + int i; + + hashed = 0; + pooled = 0; + dynamic = -1; + + for (i = 0; i < 4; i++) { + if (strncmp(name, frc->fr_ifnames[i], + sizeof(frc->fr_ifnames[i])) == 0) { + ifpflag = FRI_DYNAMIC; + dynamic = i; + return 0; + } + } + + if (gethost(name, &addr) == -1) { + fprintf(stderr, "unknown name \"%s\"\n", name); + return 0; + } + return addr; +} + + +static void dobpf(v, phrase) +int v; +char *phrase; +{ +#ifdef IPFILTER_BPF + struct bpf_program bpf; + struct pcap *p; +#endif + fakebpf_t *fb; + u_32_t l; + char *s; + int i; + + for (fr = frc; fr != NULL; fr = fr->fr_next) { + if (fr->fr_type != FR_T_NONE) { + fprintf(stderr, "cannot mix IPF and BPF matching\n"); + return; + } + fr->fr_v = v; + fr->fr_type = FR_T_BPFOPC; + + if (!strncmp(phrase, "\"0x", 2)) { + phrase++; + fb = malloc(sizeof(fakebpf_t)); + + for (i = 0, s = strtok(phrase, " \r\n\t"); s != NULL; + s = strtok(NULL, " \r\n\t"), i++) { + fb = realloc(fb, (i / 4 + 1) * sizeof(*fb)); + l = (u_32_t)strtol(s, NULL, 0); + switch (i & 3) + { + case 0 : + fb[i / 4].fb_c = l & 0xffff; + break; + case 1 : + fb[i / 4].fb_t = l & 0xff; + break; + case 2 : + fb[i / 4].fb_f = l & 0xff; + break; + case 3 : + fb[i / 4].fb_k = l; + break; + } + } + if ((i & 3) != 0) { + fprintf(stderr, + "Odd number of bytes in BPF code\n"); + exit(1); + } + i--; + fr->fr_dsize = (i / 4 + 1) * sizeof(*fb); + fr->fr_data = fb; + return; + } + +#ifdef IPFILTER_BPF + bzero((char *)&bpf, sizeof(bpf)); + p = pcap_open_dead(DLT_RAW, 1); + if (!p) { + fprintf(stderr, "pcap_open_dead failed\n"); + return; + } + + if (pcap_compile(p, &bpf, phrase, 1, 0xffffffff)) { + pcap_perror(p, "ipf"); + pcap_close(p); + fprintf(stderr, "pcap parsing failed (%s)\n", phrase); + return; + } + pcap_close(p); + + fr->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn); + fr->fr_data = malloc(fr->fr_dsize); + bcopy((char *)bpf.bf_insns, fr->fr_data, fr->fr_dsize); + if (!bpf_validate(fr->fr_data, bpf.bf_len)) { + fprintf(stderr, "BPF validation failed\n"); + return; + } +#endif + } + +#ifdef IPFILTER_BPF + if (opts & OPT_DEBUG) + bpf_dump(&bpf, 0); +#else + fprintf(stderr, "BPF filter expressions not supported\n"); + exit(1); +#endif +} + + +static void resetaddr() +{ + hashed = 0; + pooled = 0; + dynamic = -1; +} + + +static alist_t *newalist(ptr) +alist_t *ptr; +{ + alist_t *al; + + al = malloc(sizeof(*al)); + if (al == NULL) + return NULL; + al->al_not = 0; + al->al_next = ptr; + return al; +} + + +static int makepool(list) +alist_t *list; +{ + ip_pool_node_t *n, *top; + ip_pool_t pool; + alist_t *a; + int num; + + if (list == NULL) + return 0; + top = calloc(1, sizeof(*top)); + if (top == NULL) + return 0; + + for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) { + n->ipn_addr.adf_addr.in4.s_addr = a->al_1; + n->ipn_mask.adf_addr.in4.s_addr = a->al_2; + n->ipn_info = a->al_not; + if (a->al_next != NULL) { + n->ipn_next = calloc(1, sizeof(*n)); + n = n->ipn_next; + } + } + + bzero((char *)&pool, sizeof(pool)); + pool.ipo_unit = IPL_LOGIPF; + pool.ipo_list = top; + num = load_pool(&pool, ipfioctl[IPL_LOGLOOKUP]); + + while ((n = top) != NULL) { + top = n->ipn_next; + free(n); + } + return num; +} + + +static u_int makehash(list) +alist_t *list; +{ + iphtent_t *n, *top; + iphtable_t iph; + alist_t *a; + int num; + + if (list == NULL) + return 0; + top = calloc(1, sizeof(*top)); + if (top == NULL) + return 0; + + for (n = top, a = list; (n != NULL) && (a != NULL); a = a->al_next) { + n->ipe_addr.in4_addr = a->al_1; + n->ipe_mask.in4_addr = a->al_2; + n->ipe_value = 0; + if (a->al_next != NULL) { + n->ipe_next = calloc(1, sizeof(*n)); + n = n->ipe_next; + } + } + + bzero((char *)&iph, sizeof(iph)); + iph.iph_unit = IPL_LOGIPF; + iph.iph_type = IPHASH_LOOKUP; + *iph.iph_name = '\0'; + + if (load_hash(&iph, top, ipfioctl[IPL_LOGLOOKUP]) == 0) + sscanf(iph.iph_name, "%u", &num); + else + num = 0; + + while ((n = top) != NULL) { + top = n->ipe_next; + free(n); + } + return num; +} + + +void ipf_addrule(fd, ioctlfunc, ptr) +int fd; +ioctlfunc_t ioctlfunc; +void *ptr; +{ + ioctlcmd_t add, del; + frentry_t *fr; + ipfobj_t obj; + + fr = ptr; + add = 0; + del = 0; + + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(*fr); + obj.ipfo_type = IPFOBJ_FRENTRY; + obj.ipfo_ptr = ptr; + + if ((opts & OPT_DONOTHING) != 0) + fd = -1; + + if (opts & OPT_ZERORULEST) { + add = SIOCZRLST; + } else if (opts & OPT_INACTIVE) { + add = (u_int)fr->fr_hits ? SIOCINIFR : + SIOCADIFR; + del = SIOCRMIFR; + } else { + add = (u_int)fr->fr_hits ? SIOCINAFR : + SIOCADAFR; + del = SIOCRMAFR; + } + + if (fr && (opts & OPT_OUTQUE)) + fr->fr_flags |= FR_OUTQUE; + if (fr->fr_hits) + fr->fr_hits--; + if (fr && (opts & OPT_VERBOSE)) + printfr(fr, ioctlfunc); + + if (opts & OPT_DEBUG) { + binprint(fr, sizeof(*fr)); + if (fr->fr_data != NULL) + binprint(fr->fr_data, fr->fr_dsize); + } + + if ((opts & OPT_ZERORULEST) != 0) { + if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { + if ((opts & OPT_DONOTHING) == 0) { + fprintf(stderr, "%d:", yylineNum); + perror("ioctl(SIOCZRLST)"); + } + } else { +#ifdef USE_QUAD_T + printf("hits %qd bytes %qd ", + (long long)fr->fr_hits, + (long long)fr->fr_bytes); +#else + printf("hits %ld bytes %ld ", + fr->fr_hits, fr->fr_bytes); +#endif + printfr(fr, ioctlfunc); + } + } else if ((opts & OPT_REMOVE) != 0) { + if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { + if ((opts & OPT_DONOTHING) != 0) { + fprintf(stderr, "%d:", yylineNum); + perror("ioctl(delete rule)"); + } + } + } else { + if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { + if (!(opts & OPT_DONOTHING)) { + fprintf(stderr, "%d:", yylineNum); + perror("ioctl(add/insert rule)"); + } + } + } +} + +static void setsyslog() +{ + yysetdict(logwords); + yybreakondot = 1; +} + + +static void unsetsyslog() +{ + yyresetdict(); + yybreakondot = 0; +} + + +static void fillgroup(fr) +frentry_t *fr; +{ + frentry_t *f; + + for (f = frold; f != NULL; f = f->fr_next) + if (strncmp(f->fr_grhead, fr->fr_group, FR_GROUPLEN) == 0) + break; + if (f == NULL) + return; + + /* + * Only copy down matching fields if the rules are of the same type + * and are of ipf type. The only fields that are copied are those + * that impact the rule parsing itself, eg. need for knowing what the + * protocol should be for rules with port comparisons in them. + */ + if (f->fr_type != fr->fr_type || f->fr_type != FR_T_IPF) + return; + + if (fr->fr_v == 0 && f->fr_v != 0) + fr->fr_v = f->fr_v; + + if (fr->fr_mproto == 0 && f->fr_mproto != 0) + fr->fr_mproto = f->fr_mproto; + if (fr->fr_proto == 0 && f->fr_proto != 0) + fr->fr_proto = f->fr_proto; + + if ((fr->fr_mproto == 0) && ((fr->fr_flx & FI_TCPUDP) == 0) && + ((f->fr_flx & FI_TCPUDP) != 0)) + fr->fr_flx |= FI_TCPUDP; +} diff --git a/contrib/ipfilter/tools/ipfcomp.c b/contrib/ipfilter/tools/ipfcomp.c new file mode 100644 index 000000000000..262e909dd627 --- /dev/null +++ b/contrib/ipfilter/tools/ipfcomp.c @@ -0,0 +1,1347 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipfcomp.c,v 1.24.2.2 2004/04/28 10:34:44 darrenr Exp"; +#endif + +#include "ipf.h" + + +typedef struct { + int c; + int e; + int n; + int p; + int s; +} mc_t; + + +static char *portcmp[] = { "*", "==", "!=", "<", ">", "<=", ">=", "**", "***" }; +static int count = 0; + +int intcmp __P((const void *, const void *)); +static void indent __P((FILE *, int)); +static void printeq __P((FILE *, char *, int, int, int)); +static void printipeq __P((FILE *, char *, int, int, int)); +static void addrule __P((FILE *, frentry_t *)); +static void printhooks __P((FILE *, int, int, frgroup_t *)); +static void emitheader __P((frgroup_t *, u_int, u_int)); +static void emitGroup __P((int, int, void *, frentry_t *, char *, + u_int, u_int)); +static void emittail __P((void)); +static void printCgroup __P((int, frentry_t *, mc_t *, char *)); + +#define FRC_IFN 0 +#define FRC_V 1 +#define FRC_P 2 +#define FRC_FL 3 +#define FRC_TOS 4 +#define FRC_TTL 5 +#define FRC_SRC 6 +#define FRC_DST 7 +#define FRC_TCP 8 +#define FRC_SP 9 +#define FRC_DP 10 +#define FRC_OPT 11 +#define FRC_SEC 12 +#define FRC_ATH 13 +#define FRC_ICT 14 +#define FRC_ICC 15 +#define FRC_MAX 16 + + +static FILE *cfile = NULL; + +/* + * This is called once per filter rule being loaded to emit data structures + * required. + */ +void printc(fr) +frentry_t *fr; +{ + fripf_t *ipf; + u_long *ulp; + char *and; + FILE *fp; + int i; + + if (fr->fr_v != 4) + return; + if ((fr->fr_type != FR_T_IPF) && (fr->fr_type != FR_T_NONE)) + return; + if ((fr->fr_type == FR_T_IPF) && + ((fr->fr_datype != FRI_NORMAL) || (fr->fr_satype != FRI_NORMAL))) + return; + ipf = fr->fr_ipf; + + if (cfile == NULL) + cfile = fopen("ip_rules.c", "w"); + if (cfile == NULL) + return; + fp = cfile; + if (count == 0) { + fprintf(fp, "/*\n"); + fprintf(fp, "* Copyright (C) 1993-2000 by Darren Reed.\n"); + fprintf(fp, "*\n"); + fprintf(fp, "* Redistribution and use in source and binary forms are permitted\n"); + fprintf(fp, "* provided that this notice is preserved and due credit is given\n"); + fprintf(fp, "* to the original author and the contributors.\n"); + fprintf(fp, "*/\n\n"); + + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi)\n"); + fprintf(fp, "# include \n"); + fprintf(fp, "#endif\n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, +"#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux)\n"); + fprintf(fp, "# include \n"); + fprintf(fp, "#endif\n"); + fprintf(fp, +"#if defined(__FreeBSD__) && (__FreeBSD_version > 220000)\n"); + fprintf(fp, "# include \n"); + fprintf(fp, "#else\n"); + fprintf(fp, "# include \n"); + fprintf(fp, "#endif /* FreeBSD */\n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \"netinet/ip_compat.h\"\n"); + fprintf(fp, "#include \"netinet/ip_fil.h\"\n\n"); + fprintf(fp, "#include \"netinet/ip_rules.h\"\n\n"); + fprintf(fp, "#ifndef _KERNEL\n"); + fprintf(fp, "# include \n"); + fprintf(fp, "#endif /* _KERNEL */\n"); + fprintf(fp, "\n"); + fprintf(fp, "#ifdef IPFILTER_COMPILED\n"); + } + + addrule(fp, fr); + fr->fr_type |= FR_T_BUILTIN; + and = ""; + fr->fr_ref = 1; + i = sizeof(*fr); + if (i & -(1 - sizeof(*ulp))) + i += sizeof(u_long); + for (i /= sizeof(u_long), ulp = (u_long *)fr; i > 0; i--) { + fprintf(fp, "%s%#lx", and, *ulp++); + and = ", "; + } + fprintf(fp, "\n};\n"); + fr->fr_type &= ~FR_T_BUILTIN; + + count++; + + fflush(fp); +} + + +static frgroup_t *groups = NULL; + + +static void addrule(fp, fr) +FILE *fp; +frentry_t *fr; +{ + frentry_t *f, **fpp; + frgroup_t *g; + u_long *ulp; + char *and; + int i; + + f = (frentry_t *)malloc(sizeof(*f)); + bcopy((char *)fr, (char *)f, sizeof(*fr)); + if (fr->fr_ipf) { + f->fr_ipf = (fripf_t *)malloc(sizeof(*f->fr_ipf)); + bcopy((char *)fr->fr_ipf, (char *)f->fr_ipf, + sizeof(*fr->fr_ipf)); + } + + f->fr_next = NULL; + for (g = groups; g != NULL; g = g->fg_next) + if ((strncmp(g->fg_name, f->fr_group, FR_GROUPLEN) == 0) && + (g->fg_flags == (f->fr_flags & FR_INOUT))) + break; + + if (g == NULL) { + g = (frgroup_t *)calloc(1, sizeof(*g)); + g->fg_next = groups; + groups = g; + g->fg_head = f; + bcopy(f->fr_group, g->fg_name, FR_GROUPLEN); + g->fg_ref = 0; + g->fg_flags = f->fr_flags & FR_INOUT; + } + + for (fpp = &g->fg_start; *fpp != NULL; ) + fpp = &((*fpp)->fr_next); + *fpp = f; + + if (fr->fr_dsize > 0) { + fprintf(fp, "\ +static u_long ipf%s_rule_data_%s_%u[] = {\n", + f->fr_flags & FR_INQUE ? "in" : "out", + g->fg_name, g->fg_ref); + and = ""; + i = fr->fr_dsize; + ulp = fr->fr_data; + for (i /= sizeof(u_long); i > 0; i--) { + fprintf(fp, "%s%#lx", and, *ulp++); + and = ", "; + } + fprintf(fp, "\n};\n"); + } + + fprintf(fp, "\nstatic u_long %s_rule_%s_%d[] = {\n", + f->fr_flags & FR_INQUE ? "in" : "out", g->fg_name, g->fg_ref); + + g->fg_ref++; + + if (f->fr_grhead != 0) { + for (g = groups; g != NULL; g = g->fg_next) + if ((strncmp(g->fg_name, f->fr_grhead, + FR_GROUPLEN) == 0) && + g->fg_flags == (f->fr_flags & FR_INOUT)) + break; + if (g == NULL) { + g = (frgroup_t *)calloc(1, sizeof(*g)); + g->fg_next = groups; + groups = g; + g->fg_head = f; + bcopy(f->fr_grhead, g->fg_name, FR_GROUPLEN); + g->fg_ref = 0; + g->fg_flags = f->fr_flags & FR_INOUT; + } + } +} + + +int intcmp(c1, c2) +const void *c1, *c2; +{ + const mc_t *i1 = (const mc_t *)c1, *i2 = (const mc_t *)c2; + + if (i1->n == i2->n) { + return i1->c - i2->c; + } + return i2->n - i1->n; +} + + +static void indent(fp, in) +FILE *fp; +int in; +{ + for (; in; in--) + fputc('\t', fp); +} + +static void printeq(fp, var, m, max, v) +FILE *fp; +char *var; +int m, max, v; +{ + if (m == max) + fprintf(fp, "%s == %#x) {\n", var, v); + else + fprintf(fp, "(%s & %#x) == %#x) {\n", var, m, v); +} + +/* + * Parameters: var - IP# being compared + * fl - 0 for positive match, 1 for negative match + * m - netmask + * v - required address + */ +static void printipeq(fp, var, fl, m, v) +FILE *fp; +char *var; +int fl, m, v; +{ + if (m == 0xffffffff) + fprintf(fp, "%s ", var); + else + fprintf(fp, "(%s & %#x) ", var, m); + fprintf(fp, "%c", fl ? '!' : '='); + fprintf(fp, "= %#x) {\n", v); +} + + +void emit(num, dir, v, fr) +int num, dir; +void *v; +frentry_t *fr; +{ + u_int incnt, outcnt; + frgroup_t *g; + frentry_t *f; + + for (g = groups; g != NULL; g = g->fg_next) { + if (dir == 0 || dir == -1) { + if ((g->fg_flags & FR_INQUE) == 0) + continue; + for (incnt = 0, f = g->fg_start; f != NULL; + f = f->fr_next) + incnt++; + emitGroup(num, dir, v, fr, g->fg_name, incnt, 0); + } + if (dir == 1 || dir == -1) { + if ((g->fg_flags & FR_OUTQUE) == 0) + continue; + for (outcnt = 0, f = g->fg_start; f != NULL; + f = f->fr_next) + outcnt++; + emitGroup(num, dir, v, fr, g->fg_name, 0, outcnt); + } + } + + if (num == -1 && dir == -1) { + for (g = groups; g != NULL; g = g->fg_next) { + if ((g->fg_flags & FR_INQUE) != 0) { + for (incnt = 0, f = g->fg_start; f != NULL; + f = f->fr_next) + incnt++; + if (incnt > 0) + emitheader(g, incnt, 0); + } + if ((g->fg_flags & FR_OUTQUE) != 0) { + for (outcnt = 0, f = g->fg_start; f != NULL; + f = f->fr_next) + outcnt++; + if (outcnt > 0) + emitheader(g, 0, outcnt); + } + } + emittail(); + fprintf(cfile, "#endif /* IPFILTER_COMPILED */\n"); + } + +} + + +static void emitheader(grp, incount, outcount) +frgroup_t *grp; +u_int incount, outcount; +{ + static FILE *fph = NULL; + frgroup_t *g; + + if (fph == NULL) { + fph = fopen("ip_rules.h", "w"); + if (fph == NULL) + return; + + fprintf(fph, "extern int ipfrule_add __P((void));\n"); + fprintf(fph, "extern int ipfrule_remove __P((void));\n"); + } + + printhooks(cfile, incount, outcount, grp); + + if (incount) { + fprintf(fph, "\n\ +extern frentry_t *ipfrule_match_in_%s __P((fr_info_t *, u_32_t *));\n\ +extern frentry_t *ipf_rules_in_%s[%d];\n", + grp->fg_name, grp->fg_name, incount); + + for (g = groups; g != grp; g = g->fg_next) + if ((strncmp(g->fg_name, grp->fg_name, + FR_GROUPLEN) == 0) && + g->fg_flags == grp->fg_flags) + break; + if (g == grp) { + fprintf(fph, "\n\ +extern int ipfrule_add_in_%s __P((void));\n\ +extern int ipfrule_remove_in_%s __P((void));\n", grp->fg_name, grp->fg_name); + } + } + if (outcount) { + fprintf(fph, "\n\ +extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\ +extern frentry_t *ipf_rules_out_%s[%d];\n", + grp->fg_name, grp->fg_name, outcount); + + for (g = groups; g != g; g = g->fg_next) + if ((strncmp(g->fg_name, grp->fg_name, + FR_GROUPLEN) == 0) && + g->fg_flags == grp->fg_flags) + break; + if (g == grp) { + fprintf(fph, "\n\ +extern int ipfrule_add_out_%s __P((void));\n\ +extern int ipfrule_remove_out_%s __P((void));\n", + grp->fg_name, grp->fg_name); + } + } +} + +static void emittail() +{ + frgroup_t *g; + + fprintf(cfile, "\n\ +int ipfrule_add()\n\ +{\n\ + int err;\n\ +\n"); + for (g = groups; g != NULL; g = g->fg_next) + fprintf(cfile, "\ + err = ipfrule_add_%s_%s();\n\ + if (err != 0)\n\ + return err;\n", + (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); + fprintf(cfile, "\ + return 0;\n"); + fprintf(cfile, "}\n\ +\n"); + + fprintf(cfile, "\n\ +int ipfrule_remove()\n\ +{\n\ + int err;\n\ +\n"); + for (g = groups; g != NULL; g = g->fg_next) + fprintf(cfile, "\ + err = ipfrule_remove_%s_%s();\n\ + if (err != 0)\n\ + return err;\n", + (g->fg_flags & FR_INQUE) ? "in" : "out", g->fg_name); + fprintf(cfile, "\ + return 0;\n"); + fprintf(cfile, "}\n"); +} + + +static void emitGroup(num, dir, v, fr, group, incount, outcount) +int num, dir; +void *v; +frentry_t *fr; +char *group; +u_int incount, outcount; +{ + static FILE *fp = NULL; + static int header[2] = { 0, 0 }; + static char egroup[FR_GROUPLEN] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + static int openfunc = 0; + static mc_t *n = NULL; + static int sin = 0; + frentry_t *f; + frgroup_t *g; + fripf_t *ipf; + int i, in, j; + mc_t *m = v; + + if (fp == NULL) + fp = cfile; + if (fp == NULL) + return; + if (strncmp(egroup, group, FR_GROUPLEN)) { + for (sin--; sin > 0; sin--) { + indent(fp, sin); + fprintf(fp, "}\n"); + } + if (openfunc == 1) { + fprintf(fp, "\treturn fr;\n}\n"); + openfunc = 0; + if (n != NULL) { + free(n); + n = NULL; + } + } + sin = 0; + header[0] = 0; + header[1] = 0; + strncpy(egroup, group, FR_GROUPLEN); + } else if (openfunc == 1 && num < 0) { + if (n != NULL) { + free(n); + n = NULL; + } + for (sin--; sin > 0; sin--) { + indent(fp, sin); + fprintf(fp, "}\n"); + } + if (openfunc == 1) { + fprintf(fp, "\treturn fr;\n}\n"); + openfunc = 0; + } + } + + if (dir == -1) + return; + + for (g = groups; g != NULL; g = g->fg_next) { + if (dir == 0 && (g->fg_flags & FR_INQUE) == 0) + continue; + else if (dir == 1 && (g->fg_flags & FR_OUTQUE) == 0) + continue; + if (strncmp(g->fg_name, group, FR_GROUPLEN) != 0) + continue; + break; + } + + /* + * Output the array of pointers to rules for this group. + */ + if (num == -2 && dir == 0 && header[0] == 0 && incount != 0) { + fprintf(fp, "\nfrentry_t *ipf_rules_in_%s[%d] = {", + group, incount); + for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { + if ((f->fr_flags & FR_INQUE) == 0) + continue; + if ((i & 1) == 0) { + fprintf(fp, "\n\t"); + } + fprintf(fp, + "(frentry_t *)&in_rule_%s_%d", + f->fr_group, i); + if (i + 1 < incount) + fprintf(fp, ", "); + i++; + } + fprintf(fp, "\n};\n"); + } + + if (num == -2 && dir == 1 && header[1] == 0 && outcount != 0) { + fprintf(fp, "\nfrentry_t *ipf_rules_out_%s[%d] = {", + group, outcount); + for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { + if ((f->fr_flags & FR_OUTQUE) == 0) + continue; + if ((i & 1) == 0) { + fprintf(fp, "\n\t"); + } + fprintf(fp, + "(frentry_t *)&out_rule_%s_%d", + f->fr_group, i); + if (i + 1 < outcount) + fprintf(fp, ", "); + i++; + } + fprintf(fp, "\n};\n"); + fp = NULL; + } + + if (num < 0) + return; + + in = 0; + ipf = fr->fr_ipf; + + /* + * If the function header has not been printed then print it now. + */ + if (header[dir] == 0) { + int pdst = 0, psrc = 0; + + openfunc = 1; + fprintf(fp, "\nfrentry_t *ipfrule_match_%s_%s(fin, passp)\n", + (dir == 0) ? "in" : "out", group); + fprintf(fp, "fr_info_t *fin;\n"); + fprintf(fp, "u_32_t *passp;\n"); + fprintf(fp, "{\n"); + fprintf(fp, "\tfrentry_t *fr = NULL;\n"); + + /* + * Print out any variables that need to be declared. + */ + for (f = g->fg_start, i = 0; f != NULL; f = f->fr_next) { + if (incount + outcount > m[FRC_SRC].e + 1) + psrc = 1; + if (incount + outcount > m[FRC_DST].e + 1) + pdst = 1; + } + if (psrc == 1) + fprintf(fp, "\tu_32_t src = ntohl(%s);\n", + "fin->fin_fi.fi_saddr"); + if (pdst == 1) + fprintf(fp, "\tu_32_t dst = ntohl(%s);\n", + "fin->fin_fi.fi_daddr"); + } + + for (i = 0; i < FRC_MAX; i++) { + switch(m[i].c) + { + case FRC_IFN : + if (*fr->fr_ifname) + m[i].s = 1; + break; + case FRC_V : + if (ipf != NULL && ipf->fri_mip.fi_v != 0) + m[i].s = 1; + break; + case FRC_FL : + if (ipf != NULL && ipf->fri_mip.fi_flx != 0) + m[i].s = 1; + break; + case FRC_P : + if (ipf != NULL && ipf->fri_mip.fi_p != 0) + m[i].s = 1; + break; + case FRC_TTL : + if (ipf != NULL && ipf->fri_mip.fi_ttl != 0) + m[i].s = 1; + break; + case FRC_TOS : + if (ipf != NULL && ipf->fri_mip.fi_tos != 0) + m[i].s = 1; + break; + case FRC_TCP : + if (ipf == NULL) + break; + if ((ipf->fri_ip.fi_p == IPPROTO_TCP) && + fr->fr_tcpfm != 0) + m[i].s = 1; + break; + case FRC_SP : + if (ipf == NULL) + break; + if (fr->fr_scmp == FR_INRANGE) + m[i].s = 1; + else if (fr->fr_scmp == FR_OUTRANGE) + m[i].s = 1; + else if (fr->fr_scmp != 0) + m[i].s = 1; + break; + case FRC_DP : + if (ipf == NULL) + break; + if (fr->fr_dcmp == FR_INRANGE) + m[i].s = 1; + else if (fr->fr_dcmp == FR_OUTRANGE) + m[i].s = 1; + else if (fr->fr_dcmp != 0) + m[i].s = 1; + break; + case FRC_SRC : + if (ipf == NULL) + break; + if (fr->fr_satype == FRI_LOOKUP) { + ; + } else if ((fr->fr_smask != 0) || + (fr->fr_flags & FR_NOTSRCIP) != 0) + m[i].s = 1; + break; + case FRC_DST : + if (ipf == NULL) + break; + if (fr->fr_datype == FRI_LOOKUP) { + ; + } else if ((fr->fr_dmask != 0) || + (fr->fr_flags & FR_NOTDSTIP) != 0) + m[i].s = 1; + break; + case FRC_OPT : + if (ipf == NULL) + break; + if (fr->fr_optmask != 0) + m[i].s = 1; + break; + case FRC_SEC : + if (ipf == NULL) + break; + if (fr->fr_secmask != 0) + m[i].s = 1; + break; + case FRC_ATH : + if (ipf == NULL) + break; + if (fr->fr_authmask != 0) + m[i].s = 1; + break; + case FRC_ICT : + if (ipf == NULL) + break; + if ((fr->fr_icmpm & 0xff00) != 0) + m[i].s = 1; + break; + case FRC_ICC : + if (ipf == NULL) + break; + if ((fr->fr_icmpm & 0xff) != 0) + m[i].s = 1; + break; + } + } + + if (!header[dir]) { + fprintf(fp, "\n"); + header[dir] = 1; + sin = 0; + } + + qsort(m, FRC_MAX, sizeof(mc_t), intcmp); + + if (n) { + /* + * Calculate the indentation interval upto the last common + * common comparison being made. + */ + for (i = 0, in = 1; i < FRC_MAX; i++) { + if (n[i].c != m[i].c) + break; + if (n[i].s != m[i].s) + break; + if (n[i].s) { + if (n[i].n && (n[i].n > n[i].e)) { + m[i].p++; + in += m[i].p; + break; + } + if (n[i].e > 0) { + in++; + } else + break; + } + } + if (sin != in) { + for (j = sin - 1; j >= in; j--) { + indent(fp, j); + fprintf(fp, "}\n"); + } + } + } else { + in = 1; + i = 0; + } + + /* + * print out C code that implements a filter rule. + */ + for (; i < FRC_MAX; i++) { + switch(m[i].c) + { + case FRC_IFN : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if (fin->fin_ifp == "); + fprintf(fp, "ipf_rules_%s_%s[%d]->fr_ifa) {\n", + dir ? "out" : "in", group, num); + in++; + } + break; + case FRC_V : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if (fin->fin_v == %d) {\n", + ipf->fri_ip.fi_v); + in++; + } + break; + case FRC_FL : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_flx", + ipf->fri_mip.fi_flx, 0xf, + ipf->fri_ip.fi_flx); + in++; + } + break; + case FRC_P : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if (fin->fin_p == %d) {\n", + ipf->fri_ip.fi_p); + in++; + } + break; + case FRC_TTL : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_ttl", + ipf->fri_mip.fi_ttl, 0xff, + ipf->fri_ip.fi_ttl); + in++; + } + break; + case FRC_TOS : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if (fin->fin_tos"); + printeq(fp, "fin->fin_tos", + ipf->fri_mip.fi_tos, 0xff, + ipf->fri_ip.fi_tos); + in++; + } + break; + case FRC_TCP : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_tcpf", fr->fr_tcpfm, + 0xff, fr->fr_tcpf); + in++; + } + break; + case FRC_SP : + if (!m[i].s) + break; + if (fr->fr_scmp == FR_INRANGE) { + indent(fp, in); + fprintf(fp, "if ((fin->fin_data[0] > %d) && ", + fr->fr_sport); + fprintf(fp, "(fin->fin_data[0] < %d)", + fr->fr_stop); + fprintf(fp, ") {\n"); + in++; + } else if (fr->fr_scmp == FR_OUTRANGE) { + indent(fp, in); + fprintf(fp, "if ((fin->fin_data[0] < %d) || ", + fr->fr_sport); + fprintf(fp, "(fin->fin_data[0] > %d)", + fr->fr_stop); + fprintf(fp, ") {\n"); + in++; + } else if (fr->fr_scmp) { + indent(fp, in); + fprintf(fp, "if (fin->fin_data[0] %s %d)", + portcmp[fr->fr_scmp], fr->fr_sport); + fprintf(fp, " {\n"); + in++; + } + break; + case FRC_DP : + if (!m[i].s) + break; + if (fr->fr_dcmp == FR_INRANGE) { + indent(fp, in); + fprintf(fp, "if ((fin->fin_data[1] > %d) && ", + fr->fr_dport); + fprintf(fp, "(fin->fin_data[1] < %d)", + fr->fr_dtop); + fprintf(fp, ") {\n"); + in++; + } else if (fr->fr_dcmp == FR_OUTRANGE) { + indent(fp, in); + fprintf(fp, "if ((fin->fin_data[1] < %d) || ", + fr->fr_dport); + fprintf(fp, "(fin->fin_data[1] > %d)", + fr->fr_dtop); + fprintf(fp, ") {\n"); + in++; + } else if (fr->fr_dcmp) { + indent(fp, in); + fprintf(fp, "if (fin->fin_data[1] %s %d)", + portcmp[fr->fr_dcmp], fr->fr_dport); + fprintf(fp, " {\n"); + in++; + } + break; + case FRC_SRC : + if (!m[i].s) + break; + if (fr->fr_satype == FRI_LOOKUP) { + ; + } else if ((fr->fr_smask != 0) || + (fr->fr_flags & FR_NOTSRCIP) != 0) { + indent(fp, in); + fprintf(fp, "if ("); + printipeq(fp, "src", + fr->fr_flags & FR_NOTSRCIP, + fr->fr_smask, fr->fr_saddr); + in++; + } + break; + case FRC_DST : + if (!m[i].s) + break; + if (fr->fr_datype == FRI_LOOKUP) { + ; + } else if ((fr->fr_dmask != 0) || + (fr->fr_flags & FR_NOTDSTIP) != 0) { + indent(fp, in); + fprintf(fp, "if ("); + printipeq(fp, "dst", + fr->fr_flags & FR_NOTDSTIP, + fr->fr_dmask, fr->fr_daddr); + in++; + } + break; + case FRC_OPT : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_fi.fi_optmsk", + fr->fr_optmask, 0xffffffff, + fr->fr_optbits); + in++; + } + break; + case FRC_SEC : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_fi.fi_secmsk", + fr->fr_secmask, 0xffff, + fr->fr_secbits); + in++; + } + break; + case FRC_ATH : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_fi.fi_authmsk", + fr->fr_authmask, 0xffff, + fr->fr_authbits); + in++; + } + break; + case FRC_ICT : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_data[0]", + fr->fr_icmpm & 0xff00, 0xffff, + fr->fr_icmp & 0xff00); + in++; + } + break; + case FRC_ICC : + if (m[i].s) { + indent(fp, in); + fprintf(fp, "if ("); + printeq(fp, "fin->fin_data[0]", + fr->fr_icmpm & 0xff, 0xffff, + fr->fr_icmp & 0xff); + in++; + } + break; + } + + } + + indent(fp, in); + if (fr->fr_flags & FR_QUICK) { + fprintf(fp, "return (frentry_t *)&%s_rule_%s_%d;\n", + fr->fr_flags & FR_INQUE ? "in" : "out", + fr->fr_group, num); + } else { + fprintf(fp, "fr = (frentry_t *)&%s_rule_%s_%d;\n", + fr->fr_flags & FR_INQUE ? "in" : "out", + fr->fr_group, num); + } + if (n == NULL) + n = (mc_t *)malloc(sizeof(*n) * FRC_MAX); + bcopy((char *)m, (char *)n, sizeof(*n) * FRC_MAX); + sin = in; +} + + +void printC(dir) +int dir; +{ + static mc_t *m = NULL; + frgroup_t *g; + + if (m == NULL) + m = (mc_t *)calloc(1, sizeof(*m) * FRC_MAX); + + for (g = groups; g != NULL; g = g->fg_next) { + if ((dir == 0) && ((g->fg_flags & FR_INQUE) != 0)) + printCgroup(dir, g->fg_start, m, g->fg_name); + if ((dir == 1) && ((g->fg_flags & FR_OUTQUE) != 0)) + printCgroup(dir, g->fg_start, m, g->fg_name); + } + + emit(-1, dir, m, NULL); +} + + +/* + * Now print out code to implement all of the rules. + */ +static void printCgroup(dir, top, m, group) +int dir; +frentry_t *top; +mc_t *m; +char *group; +{ + frentry_t *fr, *fr1; + int i, n, rn; + u_int count; + + for (count = 0, fr1 = top; fr1 != NULL; fr1 = fr1->fr_next) { + if ((dir == 0) && ((fr1->fr_flags & FR_INQUE) != 0)) + count++; + else if ((dir == 1) && ((fr1->fr_flags & FR_OUTQUE) != 0)) + count++; + } + + if (dir == 0) + emitGroup(-2, dir, m, fr1, group, count, 0); + else if (dir == 1) + emitGroup(-2, dir, m, fr1, group, 0, count); + + /* + * Before printing each rule, check to see how many of its fields are + * matched by subsequent rules. + */ + for (fr1 = top, rn = 0; fr1 != NULL; fr1 = fr1->fr_next, rn++) { + if (!dir && !(fr1->fr_flags & FR_INQUE)) + continue; + if (dir && !(fr1->fr_flags & FR_OUTQUE)) + continue; + n = 0xfffffff; + + for (i = 0; i < FRC_MAX; i++) + m[i].e = 0; + qsort(m, FRC_MAX, sizeof(mc_t), intcmp); + + for (i = 0; i < FRC_MAX; i++) { + m[i].c = i; + m[i].e = 0; + m[i].n = 0; + m[i].s = 0; + } + + for (fr = fr1->fr_next; fr; fr = fr->fr_next) { + if (!dir && !(fr->fr_flags & FR_INQUE)) + continue; + if (dir && !(fr->fr_flags & FR_OUTQUE)) + continue; + + if ((n & 0x0001) && + !strcmp(fr1->fr_ifname, fr->fr_ifname)) { + m[FRC_IFN].e++; + m[FRC_IFN].n++; + } else + n &= ~0x0001; + + if ((n & 0x0002) && (fr1->fr_v == fr->fr_v)) { + m[FRC_V].e++; + m[FRC_V].n++; + } else + n &= ~0x0002; + + if ((n & 0x0004) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_mip.fi_flx == fr->fr_mip.fi_flx) && + (fr1->fr_ip.fi_flx == fr->fr_ip.fi_flx)) { + m[FRC_FL].e++; + m[FRC_FL].n++; + } else + n &= ~0x0004; + + if ((n & 0x0008) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_proto == fr->fr_proto)) { + m[FRC_P].e++; + m[FRC_P].n++; + } else + n &= ~0x0008; + + if ((n & 0x0010) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_ttl == fr->fr_ttl)) { + m[FRC_TTL].e++; + m[FRC_TTL].n++; + } else + n &= ~0x0010; + + if ((n & 0x0020) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_tos == fr->fr_tos)) { + m[FRC_TOS].e++; + m[FRC_TOS].n++; + } else + n &= ~0x0020; + + if ((n & 0x0040) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_tcpfm == fr->fr_tcpfm) && + (fr1->fr_tcpf == fr->fr_tcpf))) { + m[FRC_TCP].e++; + m[FRC_TCP].n++; + } else + n &= ~0x0040; + + if ((n & 0x0080) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_scmp == fr->fr_scmp) && + (fr1->fr_stop == fr->fr_stop) && + (fr1->fr_sport == fr->fr_sport))) { + m[FRC_SP].e++; + m[FRC_SP].n++; + } else + n &= ~0x0080; + + if ((n & 0x0100) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_dcmp == fr->fr_dcmp) && + (fr1->fr_dtop == fr->fr_dtop) && + (fr1->fr_dport == fr->fr_dport))) { + m[FRC_DP].e++; + m[FRC_DP].n++; + } else + n &= ~0x0100; + + if ((n & 0x0200) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_satype == FRI_LOOKUP) && + (fr->fr_satype == FRI_LOOKUP) && + (fr1->fr_srcnum == fr->fr_srcnum))) { + m[FRC_SRC].e++; + m[FRC_SRC].n++; + } else if ((n & 0x0200) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (((fr1->fr_flags & FR_NOTSRCIP) == + (fr->fr_flags & FR_NOTSRCIP)))) { + if ((fr1->fr_smask == fr->fr_smask) && + (fr1->fr_saddr == fr->fr_saddr)) + m[FRC_SRC].e++; + else + n &= ~0x0200; + if (fr1->fr_smask && + (fr1->fr_saddr & fr1->fr_smask) == + (fr->fr_saddr & fr1->fr_smask)) { + m[FRC_SRC].n++; + n |= 0x0200; + } + } else { + n &= ~0x0200; + } + + if ((n & 0x0400) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_datype == FRI_LOOKUP) && + (fr->fr_datype == FRI_LOOKUP) && + (fr1->fr_dstnum == fr->fr_dstnum))) { + m[FRC_DST].e++; + m[FRC_DST].n++; + } else if ((n & 0x0400) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (((fr1->fr_flags & FR_NOTDSTIP) == + (fr->fr_flags & FR_NOTDSTIP)))) { + if ((fr1->fr_dmask == fr->fr_dmask) && + (fr1->fr_daddr == fr->fr_daddr)) + m[FRC_DST].e++; + else + n &= ~0x0400; + if (fr1->fr_dmask && + (fr1->fr_daddr & fr1->fr_dmask) == + (fr->fr_daddr & fr1->fr_dmask)) { + m[FRC_DST].n++; + n |= 0x0400; + } + } else { + n &= ~0x0400; + } + + if ((n & 0x0800) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_optmask == fr->fr_optmask) && + (fr1->fr_optbits == fr->fr_optbits)) { + m[FRC_OPT].e++; + m[FRC_OPT].n++; + } else + n &= ~0x0800; + + if ((n & 0x1000) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_secmask == fr->fr_secmask) && + (fr1->fr_secbits == fr->fr_secbits)) { + m[FRC_SEC].e++; + m[FRC_SEC].n++; + } else + n &= ~0x1000; + + if ((n & 0x10000) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + (fr1->fr_authmask == fr->fr_authmask) && + (fr1->fr_authbits == fr->fr_authbits)) { + m[FRC_ATH].e++; + m[FRC_ATH].n++; + } else + n &= ~0x10000; + + if ((n & 0x20000) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_icmpm & 0xff00) == + (fr->fr_icmpm & 0xff00)) && + ((fr1->fr_icmp & 0xff00) == + (fr->fr_icmp & 0xff00))) { + m[FRC_ICT].e++; + m[FRC_ICT].n++; + } else + n &= ~0x20000; + + if ((n & 0x40000) && + (fr->fr_type == fr1->fr_type) && + (fr->fr_type == FR_T_IPF) && + ((fr1->fr_icmpm & 0xff) == (fr->fr_icmpm & 0xff)) && + ((fr1->fr_icmp & 0xff) == (fr->fr_icmp & 0xff))) { + m[FRC_ICC].e++; + m[FRC_ICC].n++; + } else + n &= ~0x40000; + } + /*msort(m);*/ + + if (dir == 0) + emitGroup(rn, dir, m, fr1, group, count, 0); + else if (dir == 1) + emitGroup(rn, dir, m, fr1, group, 0, count); + } +} + +static void printhooks(fp, in, out, grp) +FILE *fp; +int in; +int out; +frgroup_t *grp; +{ + frentry_t *fr; + char *group; + int dogrp, i; + char *instr; + + group = grp->fg_name; + dogrp = 0; + + if (in && out) { + fprintf(stderr, + "printhooks called with both in and out set\n"); + exit(1); + } + + if (in) { + instr = "in"; + } else if (out) { + instr = "out"; + } else { + instr = "???"; + } + fprintf(fp, "static frentry_t ipfrule_%s_%s;\n", instr, group); + + fprintf(fp, "\ +\n\ +int ipfrule_add_%s_%s()\n", instr, group); + fprintf(fp, "\ +{\n\ + int i, j, err = 0, max;\n\ + frentry_t *fp;\n"); + + if (dogrp) + fprintf(fp, "\ + frgroup_t *fg;\n"); + + fprintf(fp, "\n"); + + for (i = 0, fr = grp->fg_start; fr != NULL; i++, fr = fr->fr_next) + if (fr->fr_dsize > 0) { + fprintf(fp, "\ + ipf_rules_%s_%s[%d]->fr_data = &ipf%s_rule_data_%s_%u;\n", + instr, grp->fg_name, i, + instr, grp->fg_name, i); + } + fprintf(fp, "\ + max = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *);\n\ + for (i = 0; i < max; i++) {\n\ + fp = ipf_rules_%s_%s[i];\n\ + fp->fr_next = NULL;\n", instr, group, instr, group); + + fprintf(fp, "\ + for (j = i + 1; j < max; j++)\n\ + if (strncmp(fp->fr_group,\n\ + ipf_rules_%s_%s[j]->fr_group,\n\ + FR_GROUPLEN) == 0) {\n\ + fp->fr_next = ipf_rules_%s_%s[j];\n\ + break;\n\ + }\n", instr, group, instr, group); + if (dogrp) + fprintf(fp, "\ +\n\ + if (fp->fr_grhead != 0) {\n\ + fg = fr_addgroup(fp->fr_grhead, fp, FR_INQUE,\n\ + IPL_LOGIPF, 0);\n\ + if (fg != NULL)\n\ + fp->fr_grp = &fg->fg_start;\n\ + }\n"); + fprintf(fp, "\ + }\n\ +\n\ + fp = &ipfrule_%s_%s;\n", instr, group); + fprintf(fp, "\ + bzero((char *)fp, sizeof(*fp));\n\ + fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN;\n\ + fp->fr_flags = FR_%sQUE|FR_NOMATCH;\n\ + fp->fr_data = (void *)ipf_rules_%s_%s[0];\n", + (in != 0) ? "IN" : "OUT", instr, group); + fprintf(fp, "\ + fp->fr_dsize = sizeof(ipf_rules_%s_%s[0]);\n", + instr, group); + + fprintf(fp, "\ + fp->fr_v = 4;\n\ + fp->fr_func = (ipfunc_t)ipfrule_match_%s_%s;\n\ + err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0);\n", + instr, group); + fprintf(fp, "\treturn err;\n}\n"); + + fprintf(fp, "\n\n\ +int ipfrule_remove_%s_%s()\n", instr, group); + fprintf(fp, "\ +{\n\ + int err = 0, i;\n\ + frentry_t *fp;\n\ +\n\ + /*\n\ + * Try to remove the %sbound rule.\n", instr); + + fprintf(fp, "\ + */\n\ + if (ipfrule_%s_%s.fr_ref > 0) {\n", instr, group); + + fprintf(fp, "\ + err = EBUSY;\n\ + } else {\n"); + + fprintf(fp, "\ + i = sizeof(ipf_rules_%s_%s)/sizeof(frentry_t *) - 1;\n\ + for (; i >= 0; i--) {\n\ + fp = ipf_rules_%s_%s[i];\n\ + if (fp->fr_ref > 1) {\n\ + err = EBUSY;\n\ + break;\n\ + }\n\ + }\n\ + }\n\ + if (err == 0)\n\ + err = frrequest(IPL_LOGIPF, SIOCDELFR,\n\ + (caddr_t)&ipfrule_%s_%s, fr_active, 0);\n", + instr, group, instr, group, instr, group); + fprintf(fp, "\ + if (err)\n\ + return err;\n\ +\n\n"); + + fprintf(fp, "\treturn err;\n}\n"); +} diff --git a/contrib/ipfilter/tools/ipfs.c b/contrib/ipfilter/tools/ipfs.c new file mode 100644 index 000000000000..49e7e520a973 --- /dev/null +++ b/contrib/ipfilter/tools/ipfs.c @@ -0,0 +1,855 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1999-2001, 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#ifdef __FreeBSD__ +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 +# include +# endif +# endif +#endif +#include +#include +#include +#include +#include +#if !defined(__SVR4) && !defined(__GNUC__) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#include +#include +#include +#include +#include "ipf.h" +#include "ipl.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp"; +#endif + +#ifndef IPF_SAVEDIR +# define IPF_SAVEDIR "/var/db/ipf" +#endif +#ifndef IPF_NATFILE +# define IPF_NATFILE "ipnat.ipf" +#endif +#ifndef IPF_STATEFILE +# define IPF_STATEFILE "ipstate.ipf" +#endif + +#if !defined(__SVR4) && defined(__GNUC__) +extern char *index __P((const char *, int)); +#endif + +extern char *optarg; +extern int optind; + +int main __P((int, char *[])); +void usage __P((void)); +int changestateif __P((char *, char *)); +int changenatif __P((char *, char *)); +int readstate __P((int, char *)); +int readnat __P((int, char *)); +int writestate __P((int, char *)); +int opendevice __P((char *)); +void closedevice __P((int)); +int setlock __P((int, int)); +int writeall __P((char *)); +int readall __P((char *)); +int writenat __P((int, char *)); + +int opts = 0; +char *progname; + + +void usage() +{ + fprintf(stderr, "usage: %s [-nv] -l\n", progname); + fprintf(stderr, "usage: %s [-nv] -u\n", progname); + fprintf(stderr, "usage: %s [-nv] [-d ] -R\n", progname); + fprintf(stderr, "usage: %s [-nv] [-d ] -W\n", progname); + fprintf(stderr, "usage: %s [-nNSv] [-f ] -r\n", progname); + fprintf(stderr, "usage: %s [-nNSv] [-f ] -w\n", progname); + fprintf(stderr, "usage: %s [-nNSv] -f -i ,\n", + progname); + exit(1); +} + + +/* + * Change interface names in state information saved out to disk. + */ +int changestateif(ifs, fname) +char *ifs, *fname; +{ + int fd, olen, nlen, rw; + ipstate_save_t ips; + off_t pos; + char *s; + + s = strchr(ifs, ','); + if (!s) + usage(); + *s++ = '\0'; + nlen = strlen(s); + olen = strlen(ifs); + if (nlen >= sizeof(ips.ips_is.is_ifname) || + olen >= sizeof(ips.ips_is.is_ifname)) + usage(); + + fd = open(fname, O_RDWR); + if (fd == -1) { + perror("open"); + exit(1); + } + + for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) { + rw = 0; + if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) { + strcpy(ips.ips_is.is_ifname[0], s); + rw = 1; + } + if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) { + strcpy(ips.ips_is.is_ifname[1], s); + rw = 1; + } + if (rw == 1) { + if (lseek(fd, pos, SEEK_SET) != pos) { + perror("lseek"); + exit(1); + } + if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) { + perror("write"); + exit(1); + } + } + pos = lseek(fd, 0, SEEK_CUR); + } + close(fd); + + return 0; +} + + +/* + * Change interface names in NAT information saved out to disk. + */ +int changenatif(ifs, fname) +char *ifs, *fname; +{ + int fd, olen, nlen, rw; + nat_save_t ipn; + nat_t *nat; + off_t pos; + char *s; + + s = strchr(ifs, ','); + if (!s) + usage(); + *s++ = '\0'; + nlen = strlen(s); + olen = strlen(ifs); + nat = &ipn.ipn_nat; + if (nlen >= sizeof(nat->nat_ifnames[0]) || + olen >= sizeof(nat->nat_ifnames[0])) + usage(); + + fd = open(fname, O_RDWR); + if (fd == -1) { + perror("open"); + exit(1); + } + + for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) { + rw = 0; + if (!strncmp(nat->nat_ifnames[0], ifs, olen + 1)) { + strcpy(nat->nat_ifnames[0], s); + rw = 1; + } + if (!strncmp(nat->nat_ifnames[1], ifs, olen + 1)) { + strcpy(nat->nat_ifnames[1], s); + rw = 1; + } + if (rw == 1) { + if (lseek(fd, pos, SEEK_SET) != pos) { + perror("lseek"); + exit(1); + } + if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) { + perror("write"); + exit(1); + } + } + pos = lseek(fd, 0, SEEK_CUR); + } + close(fd); + + return 0; +} + + +int main(argc,argv) +int argc; +char *argv[]; +{ + int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; + char *dirname = NULL, *filename = NULL, *ifs = NULL; + + progname = argv[0]; + while ((c = getopt(argc, argv, "d:f:lNnSRruvWw")) != -1) + switch (c) + { + case 'd' : + if ((set == 0) && !dirname && !filename) + dirname = optarg; + else + usage(); + break; + case 'f' : + if ((set != 0) && !dirname && !filename) + filename = optarg; + else + usage(); + break; + case 'i' : + ifs = optarg; + set = 1; + break; + case 'l' : + if (filename || dirname || set) + usage(); + lock = 1; + set = 1; + break; + case 'n' : + opts |= OPT_DONOTHING; + break; + case 'N' : + if ((ns >= 0) || dirname || (rw != -1) || set) + usage(); + ns = 0; + set = 1; + break; + case 'r' : + if (dirname || (rw != -1) || (ns == -1)) + usage(); + rw = 0; + set = 1; + break; + case 'R' : + rw = 2; + set = 1; + break; + case 'S' : + if ((ns >= 0) || dirname || (rw != -1) || set) + usage(); + ns = 1; + set = 1; + break; + case 'u' : + if (filename || dirname || set) + usage(); + lock = 0; + set = 1; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + case 'w' : + if (dirname || (rw != -1) || (ns == -1)) + usage(); + rw = 1; + set = 1; + break; + case 'W' : + rw = 3; + set = 1; + break; + case '?' : + default : + usage(); + } + + if (ifs) { + if (!filename || ns < 0) + usage(); + if (ns == 0) + return changenatif(ifs, filename); + else + return changestateif(ifs, filename); + } + + if ((ns >= 0) || (lock >= 0)) { + if (lock >= 0) + devfd = opendevice(NULL); + else if (ns >= 0) { + if (ns == 1) + devfd = opendevice(IPSTATE_NAME); + else if (ns == 0) + devfd = opendevice(IPNAT_NAME); + } + if (devfd == -1) + exit(1); + } + + if (lock >= 0) + err = setlock(devfd, lock); + else if (rw >= 0) { + if (rw & 1) { /* WRITE */ + if (rw & 2) + err = writeall(dirname); + else { + if (ns == 0) + err = writenat(devfd, filename); + else if (ns == 1) + err = writestate(devfd, filename); + } + } else { + if (rw & 2) + err = readall(dirname); + else { + if (ns == 0) + err = readnat(devfd, filename); + else if (ns == 1) + err = readstate(devfd, filename); + } + } + } + return err; +} + + +int opendevice(ipfdev) +char *ipfdev; +{ + int fd = -1; + + if (opts & OPT_DONOTHING) + return -2; + + if (!ipfdev) + ipfdev = IPL_NAME; + + if ((fd = open(ipfdev, O_RDWR)) == -1) + if ((fd = open(ipfdev, O_RDONLY)) == -1) + perror("open device"); + return fd; +} + + +void closedevice(fd) +int fd; +{ + close(fd); +} + + +int setlock(fd, lock) +int fd, lock; +{ + if (opts & OPT_VERBOSE) + printf("Turn lock %s\n", lock ? "on" : "off"); + if (!(opts & OPT_DONOTHING)) { + if (ioctl(fd, SIOCSTLCK, &lock) == -1) { + perror("SIOCSTLCK"); + return 1; + } + if (opts & OPT_VERBOSE) + printf("Lock now %s\n", lock ? "on" : "off"); + } + return 0; +} + + +int writestate(fd, file) +int fd; +char *file; +{ + ipstate_save_t ips, *ipsp; + ipfobj_t obj; + int wfd = -1; + + if (!file) + file = IPF_STATEFILE; + + wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); + if (wfd == -1) { + fprintf(stderr, "%s ", file); + perror("state:open"); + return 1; + } + + ipsp = &ips; + bzero((char *)&obj, sizeof(obj)); + bzero((char *)ipsp, sizeof(ips)); + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(*ipsp); + obj.ipfo_type = IPFOBJ_STATESAVE; + obj.ipfo_ptr = ipsp; + + do { + + if (opts & OPT_VERBOSE) + printf("Getting state from addr %p\n", ips.ips_next); + if (ioctl(fd, SIOCSTGET, &obj)) { + if (errno == ENOENT) + break; + perror("state:SIOCSTGET"); + close(wfd); + return 1; + } + if (opts & OPT_VERBOSE) + printf("Got state next %p\n", ips.ips_next); + if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) { + perror("state:write"); + close(wfd); + return 1; + } + } while (ips.ips_next != NULL); + close(wfd); + + return 0; +} + + +int readstate(fd, file) +int fd; +char *file; +{ + ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; + int sfd = -1, i; + ipfobj_t obj; + + if (!file) + file = IPF_STATEFILE; + + sfd = open(file, O_RDONLY, 0600); + if (sfd == -1) { + fprintf(stderr, "%s ", file); + perror("open"); + return 1; + } + + bzero((char *)&ips, sizeof(ips)); + + /* + * 1. Read all state information in. + */ + do { + i = read(sfd, &ips, sizeof(ips)); + if (i == -1) { + perror("read"); + close(sfd); + return 1; + } + if (i == 0) + break; + if (i != sizeof(ips)) { + fprintf(stderr, "state:incomplete read: %d != %d\n", + i, (int)sizeof(ips)); + close(sfd); + return 1; + } + is = (ipstate_save_t *)malloc(sizeof(*is)); + if(!is) { + fprintf(stderr, "malloc failed\n"); + return 1; + } + + bcopy((char *)&ips, (char *)is, sizeof(ips)); + + /* + * Check to see if this is the first state entry that will + * reference a particular rule and if so, flag it as such + * else just adjust the rule pointer to become a pointer to + * the other. We do this so we have a means later for tracking + * who is referencing us when we get back the real pointer + * in is_rule after doing the ioctl. + */ + for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next) + if (is1->ips_rule == is->ips_rule) + break; + if (is1 == NULL) + is->ips_is.is_flags |= SI_NEWFR; + else + is->ips_rule = (void *)&is1->ips_rule; + + /* + * Use a tail-queue type list (add things to the end).. + */ + is->ips_next = NULL; + if (!ipshead) + ipshead = is; + if (ipstail) + ipstail->ips_next = is; + ipstail = is; + } while (1); + + close(sfd); + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(*is); + obj.ipfo_type = IPFOBJ_STATESAVE; + + for (is = ipshead; is; is = is->ips_next) { + if (opts & OPT_VERBOSE) + printf("Loading new state table entry\n"); + if (is->ips_is.is_flags & SI_NEWFR) { + if (opts & OPT_VERBOSE) + printf("Loading new filter rule\n"); + } + + obj.ipfo_ptr = is; + if (!(opts & OPT_DONOTHING)) + if (ioctl(fd, SIOCSTPUT, &obj)) { + perror("SIOCSTPUT"); + return 1; + } + + if (is->ips_is.is_flags & SI_NEWFR) { + if (opts & OPT_VERBOSE) + printf("Real rule addr %p\n", is->ips_rule); + for (is1 = is->ips_next; is1; is1 = is1->ips_next) + if (is1->ips_rule == (frentry_t *)&is->ips_rule) + is1->ips_rule = is->ips_rule; + } + } + + return 0; +} + + +int readnat(fd, file) +int fd; +char *file; +{ + nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL; + ipfobj_t obj; + int nfd, i; + nat_t *nat; + char *s; + int n; + + nfd = -1; + in = NULL; + ipnhead = NULL; + ipntail = NULL; + + if (!file) + file = IPF_NATFILE; + + nfd = open(file, O_RDONLY); + if (nfd == -1) { + fprintf(stderr, "%s ", file); + perror("nat:open"); + return 1; + } + + bzero((char *)&ipn, sizeof(ipn)); + + /* + * 1. Read all state information in. + */ + do { + i = read(nfd, &ipn, sizeof(ipn)); + if (i == -1) { + perror("read"); + close(nfd); + return 1; + } + if (i == 0) + break; + if (i != sizeof(ipn)) { + fprintf(stderr, "nat:incomplete read: %d != %d\n", + i, (int)sizeof(ipn)); + close(nfd); + return 1; + } + + in = (nat_save_t *)malloc(ipn.ipn_dsize); + if (!in) + break; + + if (ipn.ipn_dsize > sizeof(ipn)) { + n = ipn.ipn_dsize - sizeof(ipn); + if (n > 0) { + s = in->ipn_data + sizeof(in->ipn_data); + i = read(nfd, s, n); + if (i == 0) + break; + if (i != n) { + fprintf(stderr, + "nat:incomplete read: %d != %d\n", + i, n); + close(nfd); + return 1; + } + } + } + bcopy((char *)&ipn, (char *)in, sizeof(ipn)); + + /* + * Check to see if this is the first NAT entry that will + * reference a particular rule and if so, flag it as such + * else just adjust the rule pointer to become a pointer to + * the other. We do this so we have a means later for tracking + * who is referencing us when we get back the real pointer + * in is_rule after doing the ioctl. + */ + nat = &in->ipn_nat; + if (nat->nat_fr != NULL) { + for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next) + if (in1->ipn_rule == nat->nat_fr) + break; + if (in1 == NULL) + nat->nat_flags |= SI_NEWFR; + else + nat->nat_fr = &in1->ipn_fr; + } + + /* + * Use a tail-queue type list (add things to the end).. + */ + in->ipn_next = NULL; + if (!ipnhead) + ipnhead = in; + if (ipntail) + ipntail->ipn_next = in; + ipntail = in; + } while (1); + + close(nfd); + nfd = -1; + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_type = IPFOBJ_NATSAVE; + + for (in = ipnhead; in; in = in->ipn_next) { + if (opts & OPT_VERBOSE) + printf("Loading new NAT table entry\n"); + nat = &in->ipn_nat; + if (nat->nat_flags & SI_NEWFR) { + if (opts & OPT_VERBOSE) + printf("Loading new filter rule\n"); + } + + obj.ipfo_ptr = in; + obj.ipfo_size = in->ipn_dsize; + if (!(opts & OPT_DONOTHING)) + if (ioctl(fd, SIOCSTPUT, &obj)) { + fprintf(stderr, "in=%p:", in); + perror("SIOCSTPUT"); + return 1; + } + + if (nat->nat_flags & SI_NEWFR) { + if (opts & OPT_VERBOSE) + printf("Real rule addr %p\n", nat->nat_fr); + for (in1 = in->ipn_next; in1; in1 = in1->ipn_next) + if (in1->ipn_rule == &in->ipn_fr) + in1->ipn_rule = nat->nat_fr; + } + } + + return 0; +} + + +int writenat(fd, file) +int fd; +char *file; +{ + nat_save_t *ipnp = NULL, *next = NULL; + ipfobj_t obj; + int nfd = -1; + natget_t ng; + + if (!file) + file = IPF_NATFILE; + + nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); + if (nfd == -1) { + fprintf(stderr, "%s ", file); + perror("nat:open"); + return 1; + } + + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_type = IPFOBJ_NATSAVE; + + do { + if (opts & OPT_VERBOSE) + printf("Getting nat from addr %p\n", ipnp); + ng.ng_ptr = next; + ng.ng_sz = 0; + if (ioctl(fd, SIOCSTGSZ, &ng)) { + perror("nat:SIOCSTGSZ"); + close(nfd); + if (ipnp != NULL) + free(ipnp); + return 1; + } + + if (opts & OPT_VERBOSE) + printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr); + + if (ng.ng_sz == 0) + break; + + if (!ipnp) + ipnp = malloc(ng.ng_sz); + else + ipnp = realloc((char *)ipnp, ng.ng_sz); + if (!ipnp) { + fprintf(stderr, + "malloc for %d bytes failed\n", ng.ng_sz); + break; + } + + bzero((char *)ipnp, ng.ng_sz); + obj.ipfo_size = ng.ng_sz; + obj.ipfo_ptr = ipnp; + ipnp->ipn_dsize = ng.ng_sz; + ipnp->ipn_next = next; + if (ioctl(fd, SIOCSTGET, &obj)) { + if (errno == ENOENT) + break; + perror("nat:SIOCSTGET"); + close(nfd); + free(ipnp); + return 1; + } + + if (opts & OPT_VERBOSE) + printf("Got nat next %p ipn_dsize %d ng_sz %d\n", + ipnp->ipn_next, ipnp->ipn_dsize, ng.ng_sz); + if (write(nfd, ipnp, ipnp->ipn_dsize) != ipnp->ipn_dsize) { + perror("nat:write"); + close(nfd); + free(ipnp); + return 1; + } + next = ipnp->ipn_next; + } while (ipnp && next); + if (ipnp != NULL) + free(ipnp); + close(nfd); + + return 0; +} + + +int writeall(dirname) +char *dirname; +{ + int fd, devfd; + + if (!dirname) + dirname = IPF_SAVEDIR; + + if (chdir(dirname)) { + fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname); + perror("chdir(IPF_SAVEDIR)"); + return 1; + } + + fd = opendevice(NULL); + if (fd == -1) + return 1; + if (setlock(fd, 1)) { + close(fd); + return 1; + } + + devfd = opendevice(IPSTATE_NAME); + if (devfd == -1) + goto bad; + if (writestate(devfd, NULL)) + goto bad; + close(devfd); + + devfd = opendevice(IPNAT_NAME); + if (devfd == -1) + goto bad; + if (writenat(devfd, NULL)) + goto bad; + close(devfd); + + if (setlock(fd, 0)) { + close(fd); + return 1; + } + + close(fd); + return 0; + +bad: + setlock(fd, 0); + close(fd); + return 1; +} + + +int readall(dirname) +char *dirname; +{ + int fd, devfd; + + if (!dirname) + dirname = IPF_SAVEDIR; + + if (chdir(dirname)) { + perror("chdir(IPF_SAVEDIR)"); + return 1; + } + + fd = opendevice(NULL); + if (fd == -1) + return 1; + if (setlock(fd, 1)) { + close(fd); + return 1; + } + + devfd = opendevice(IPSTATE_NAME); + if (devfd == -1) + return 1; + if (readstate(devfd, NULL)) + return 1; + close(devfd); + + devfd = opendevice(IPNAT_NAME); + if (devfd == -1) + return 1; + if (readnat(devfd, NULL)) + return 1; + close(devfd); + + if (setlock(fd, 0)) { + close(fd); + return 1; + } + + return 0; +} diff --git a/contrib/ipfilter/tools/ipfstat.c b/contrib/ipfilter/tools/ipfstat.c new file mode 100644 index 000000000000..fbd6c3541283 --- /dev/null +++ b/contrib/ipfilter/tools/ipfstat.c @@ -0,0 +1,1792 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001, 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#ifdef __FreeBSD__ +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 +# include +# endif +# endif +#endif +#include +#include +#ifdef linux +# include +#else +# include +#endif +#include +#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) +# include +#endif +#include "ipf.h" +#include "netinet/ipl.h" +#if defined(STATETOP) +# if defined(_BSDI_VERSION) +# undef STATETOP +# endif +# if defined(__FreeBSD__) && \ + (!defined(__FreeBSD_version) || (__FreeBSD_version < 430000)) +# undef STATETOP +# endif +# if defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000) +# undef STATETOP +# endif +# if defined(sun) +# if defined(__svr4__) || defined(__SVR4) +# include +# else +# undef STATETOP /* NOT supported on SunOS4 */ +# endif +# endif +#endif +#if defined(STATETOP) && !defined(linux) +# include +# include +#endif +#ifdef STATETOP +# include +# include +# if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \ + defined(__sgi) +# ifdef ERR +# undef ERR +# endif +# include +# else /* SOLARIS */ +# include +# endif /* SOLARIS */ +#endif /* STATETOP */ +#include "kmem.h" +#if defined(__NetBSD__) || (__OpenBSD__) +# include +#endif + +#if !defined(lint) +static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipfstat.c,v 1.44.2.11 2005/03/30 14:09:57 darrenr Exp"; +#endif + +#ifdef __hpux +# define nlist nlist64 +#endif + +extern char *optarg; +extern int optind; +extern int opterr; + +#define PRINTF (void)printf +#define FPRINTF (void)fprintf +#define F_IN 0 +#define F_OUT 1 +#define F_ACIN 2 +#define F_ACOUT 3 +static char *filters[4] = { "ipfilter(in)", "ipfilter(out)", + "ipacct(in)", "ipacct(out)" }; +static int state_logging = -1; + +int opts = 0; +int use_inet6 = 0; +int live_kernel = 1; +int state_fd = -1; +int ipf_fd = -1; + +#ifdef STATETOP +#define STSTRSIZE 80 +#define STGROWSIZE 16 +#define HOSTNMLEN 40 + +#define STSORT_PR 0 +#define STSORT_PKTS 1 +#define STSORT_BYTES 2 +#define STSORT_TTL 3 +#define STSORT_SRCIP 4 +#define STSORT_SRCPT 5 +#define STSORT_DSTIP 6 +#define STSORT_DSTPT 7 +#define STSORT_MAX STSORT_DSTPT +#define STSORT_DEFAULT STSORT_BYTES + + +typedef struct statetop { + i6addr_t st_src; + i6addr_t st_dst; + u_short st_sport; + u_short st_dport; + u_char st_p; + u_char st_v; + u_char st_state[2]; + U_QUAD_T st_pkts; + U_QUAD_T st_bytes; + u_long st_age; +} statetop_t; +#endif + +int main __P((int, char *[])); + +static void showstats __P((friostat_t *, u_32_t)); +static void showfrstates __P((ipfrstat_t *)); +static void showlist __P((friostat_t *)); +static void showipstates __P((ips_stat_t *)); +static void showauthstates __P((fr_authstat_t *)); +static void showgroups __P((friostat_t *)); +static void usage __P((char *)); +static void printlist __P((frentry_t *, char *)); +static void parse_ipportstr __P((const char *, i6addr_t *, int *)); +static void ipfstate_live __P((char *, friostat_t **, ips_stat_t **, + ipfrstat_t **, fr_authstat_t **, u_32_t *)); +static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **, + ipfrstat_t **, fr_authstat_t **, u_32_t *)); +#ifdef STATETOP +static void topipstates __P((i6addr_t, i6addr_t, int, int, int, + int, int, int)); +static void sig_break __P((int)); +static void sig_resize __P((int)); +static char *getip __P((int, i6addr_t *)); +static char *ttl_to_string __P((long)); +static int sort_p __P((const void *, const void *)); +static int sort_pkts __P((const void *, const void *)); +static int sort_bytes __P((const void *, const void *)); +static int sort_ttl __P((const void *, const void *)); +static int sort_srcip __P((const void *, const void *)); +static int sort_srcpt __P((const void *, const void *)); +static int sort_dstip __P((const void *, const void *)); +static int sort_dstpt __P((const void *, const void *)); +#endif + + +static void usage(name) +char *name; +{ +#ifdef USE_INET6 + fprintf(stderr, "Usage: %s [-6aAdfghIilnoRsv]\n", name); +#else + fprintf(stderr, "Usage: %s [-aAdfghIilnoRsv]\n", name); +#endif + fprintf(stderr, " %s [-M corefile] [-N symbol-list]\n", name); +#ifdef USE_INET6 + fprintf(stderr, " %s -t [-6C] ", name); +#else + fprintf(stderr, " %s -t [-C] ", name); +#endif + fprintf(stderr, "[-D destination address] [-P protocol] [-S source address] [-T refresh time]\n"); + exit(1); +} + + +int main(argc,argv) +int argc; +char *argv[]; +{ + fr_authstat_t frauthst; + fr_authstat_t *frauthstp = &frauthst; + friostat_t fio; + friostat_t *fiop = &fio; + ips_stat_t ipsst; + ips_stat_t *ipsstp = &ipsst; + ipfrstat_t ifrst; + ipfrstat_t *ifrstp = &ifrst; + char *device = IPL_NAME, *memf = NULL; + char *options, *kern = NULL; + int c, myoptind; + + int protocol = -1; /* -1 = wild card for any protocol */ + int refreshtime = 1; /* default update time */ + int sport = -1; /* -1 = wild card for any source port */ + int dport = -1; /* -1 = wild card for any dest port */ + int topclosed = 0; /* do not show closed tcp sessions */ + i6addr_t saddr, daddr; + u_32_t frf; + +#ifdef USE_INET6 + options = "6aACdfghIilnostvD:M:N:P:RS:T:"; +#else + options = "aACdfghIilnostvD:M:N:P:RS:T:"; +#endif + + saddr.in4.s_addr = INADDR_ANY; /* default any v4 source addr */ + daddr.in4.s_addr = INADDR_ANY; /* default any v4 dest addr */ +#ifdef USE_INET6 + saddr.in6 = in6addr_any; /* default any v6 source addr */ + daddr.in6 = in6addr_any; /* default any v6 dest addr */ +#endif + + /* Don't warn about invalid flags when we run getopt for the 1st time */ + opterr = 0; + + /* + * Parse these two arguments now lest there be any buffer overflows + * in the parsing of the rest. + */ + myoptind = optind; + while ((c = getopt(argc, argv, options)) != -1) { + switch (c) + { + case 'M' : + memf = optarg; + live_kernel = 0; + break; + case 'N' : + kern = optarg; + live_kernel = 0; + break; + } + } + optind = myoptind; + + if (live_kernel == 1) { + if ((state_fd = open(IPSTATE_NAME, O_RDONLY)) == -1) { + perror("open(IPSTATE_NAME)"); + exit(-1); + } + if ((ipf_fd = open(device, O_RDONLY)) == -1) { + fprintf(stderr, "open(%s)", device); + perror(""); + exit(-1); + } + } + + if (kern != NULL || memf != NULL) { + (void)setgid(getgid()); + (void)setuid(getuid()); + } + + if (live_kernel == 1) + (void) checkrev(device); + if (openkmem(kern, memf) == -1) + exit(-1); + + (void)setgid(getgid()); + (void)setuid(getuid()); + + opterr = 1; + + while ((c = getopt(argc, argv, options)) != -1) + { + switch (c) + { +#ifdef USE_INET6 + case '6' : + use_inet6 = 1; + break; +#endif + case 'a' : + opts |= OPT_ACCNT|OPT_SHOWLIST; + break; + case 'A' : + opts |= OPT_AUTHSTATS; + break; + case 'C' : + topclosed = 1; + break; + case 'd' : + opts |= OPT_DEBUG; + break; + case 'D' : + parse_ipportstr(optarg, &daddr, &dport); + break; + case 'f' : + opts |= OPT_FRSTATES; + break; + case 'g' : + opts |= OPT_GROUPS; + break; + case 'h' : + opts |= OPT_HITS; + break; + case 'i' : + opts |= OPT_INQUE|OPT_SHOWLIST; + break; + case 'I' : + opts |= OPT_INACTIVE; + break; + case 'l' : + opts |= OPT_SHOWLIST; + break; + case 'M' : + break; + case 'N' : + break; + case 'n' : + opts |= OPT_SHOWLINENO; + break; + case 'o' : + opts |= OPT_OUTQUE|OPT_SHOWLIST; + break; + case 'P' : + protocol = getproto(optarg); + if (protocol == -1) { + fprintf(stderr, "%s: Invalid protocol: %s\n", + argv[0], optarg); + exit(-2); + } + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 's' : + opts |= OPT_IPSTATES; + break; + case 'S' : + parse_ipportstr(optarg, &saddr, &sport); + break; + case 't' : +#ifdef STATETOP + opts |= OPT_STATETOP; + break; +#else + fprintf(stderr, + "%s: state top facility not compiled in\n", + argv[0]); + exit(-2); +#endif + case 'T' : + if (!sscanf(optarg, "%d", &refreshtime) || + (refreshtime <= 0)) { + fprintf(stderr, + "%s: Invalid refreshtime < 1 : %s\n", + argv[0], optarg); + exit(-2); + } + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + default : + usage(argv[0]); + break; + } + } + + if (live_kernel == 1) { + bzero((char *)&fio, sizeof(fio)); + bzero((char *)&ipsst, sizeof(ipsst)); + bzero((char *)&ifrst, sizeof(ifrst)); + + ipfstate_live(device, &fiop, &ipsstp, &ifrstp, + &frauthstp, &frf); + } else + ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); + + if (opts & OPT_IPSTATES) { + showipstates(ipsstp); + } else if (opts & OPT_SHOWLIST) { + showlist(fiop); + if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){ + opts &= ~OPT_OUTQUE; + showlist(fiop); + } + } else if (opts & OPT_FRSTATES) + showfrstates(ifrstp); +#ifdef STATETOP + else if (opts & OPT_STATETOP) + topipstates(saddr, daddr, sport, dport, protocol, + use_inet6 ? 6 : 4, refreshtime, topclosed); +#endif + else if (opts & OPT_AUTHSTATS) + showauthstates(frauthstp); + else if (opts & OPT_GROUPS) + showgroups(fiop); + else + showstats(fiop, frf); + + return 0; +} + + +/* + * Fill in the stats structures from the live kernel, using a combination + * of ioctl's and copying directly from kernel memory. + */ +static void ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) +char *device; +friostat_t **fiopp; +ips_stat_t **ipsstpp; +ipfrstat_t **ifrstpp; +fr_authstat_t **frauthstpp; +u_32_t *frfp; +{ + ipfobj_t ipfo; + + if (checkrev(device) == -1) { + fprintf(stderr, "User/kernel version check failed\n"); + exit(1); + } + + if ((opts & OPT_AUTHSTATS) == 0) { + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(friostat_t); + ipfo.ipfo_ptr = (void *)*fiopp; + ipfo.ipfo_type = IPFOBJ_IPFSTAT; + + if (ioctl(ipf_fd, SIOCGETFS, &ipfo) == -1) { + perror("ioctl(ipf:SIOCGETFS)"); + exit(-1); + } + + if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1) + perror("ioctl(SIOCGETFF)"); + } + + if ((opts & OPT_IPSTATES) != 0) { + + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(ips_stat_t); + ipfo.ipfo_ptr = (void *)*ipsstpp; + ipfo.ipfo_type = IPFOBJ_STATESTAT; + + if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { + perror("ioctl(state:SIOCGETFS)"); + exit(-1); + } + if (ioctl(state_fd, SIOCGETLG, &state_logging) == -1) { + perror("ioctl(state:SIOCGETLG)"); + exit(-1); + } + } + + if ((opts & OPT_FRSTATES) != 0) { + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(ipfrstat_t); + ipfo.ipfo_ptr = (void *)*ifrstpp; + ipfo.ipfo_type = IPFOBJ_FRAGSTAT; + + if (ioctl(ipf_fd, SIOCGFRST, &ipfo) == -1) { + perror("ioctl(SIOCGFRST)"); + exit(-1); + } + } + + if (opts & OPT_VERBOSE) + PRINTF("opts %#x name %s\n", opts, device); + + if ((opts & OPT_AUTHSTATS) != 0) { + if (ipf_fd >= 0) { + close(ipf_fd); + ipf_fd = -1; + } + device = IPAUTH_NAME; + if ((ipf_fd = open(device, O_RDONLY)) == -1) { + perror("open"); + exit(-1); + } + + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(fr_authstat_t); + ipfo.ipfo_ptr = (void *)*frauthstpp; + ipfo.ipfo_type = IPFOBJ_AUTHSTAT; + + if (ioctl(ipf_fd, SIOCATHST, &ipfo) == -1) { + perror("ioctl(SIOCATHST)"); + exit(-1); + } + } +} + + +/* + * Build up the stats structures from data held in the "core" memory. + * This is mainly useful when looking at data in crash dumps and ioctl's + * just won't work any more. + */ +static void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) +char *kernel; +friostat_t **fiopp; +ips_stat_t **ipsstpp; +ipfrstat_t **ifrstpp; +fr_authstat_t **frauthstpp; +u_32_t *frfp; +{ + static fr_authstat_t frauthst, *frauthstp; + static ips_stat_t ipsst, *ipsstp; + static ipfrstat_t ifrst, *ifrstp; + static friostat_t fio, *fiop; + int temp; + + void *rules[2][2]; + struct nlist deadlist[43] = { + { "fr_authstats" }, /* 0 */ + { "fae_list" }, + { "ipauth" }, + { "fr_authlist" }, + { "fr_authstart" }, + { "fr_authend" }, /* 5 */ + { "fr_authnext" }, + { "fr_auth" }, + { "fr_authused" }, + { "fr_authsize" }, + { "fr_defaultauthage" }, /* 10 */ + { "fr_authpkts" }, + { "fr_auth_lock" }, + { "frstats" }, + { "ips_stats" }, + { "ips_num" }, /* 15 */ + { "ips_wild" }, + { "ips_list" }, + { "ips_table" }, + { "fr_statemax" }, + { "fr_statesize" }, /* 20 */ + { "fr_state_doflush" }, + { "fr_state_lock" }, + { "ipfr_heads" }, + { "ipfr_nattab" }, + { "ipfr_stats" }, /* 25 */ + { "ipfr_inuse" }, + { "fr_ipfrttl" }, + { "fr_frag_lock" }, + { "ipfr_timer_id" }, + { "fr_nat_lock" }, /* 30 */ + { "ipfilter" }, + { "ipfilter6" }, + { "ipacct" }, + { "ipacct6" }, + { "ipl_frouteok" }, /* 35 */ + { "fr_running" }, + { "ipfgroups" }, + { "fr_active" }, + { "fr_pass" }, + { "fr_flags" }, /* 40 */ + { "ipstate_logging" }, + { NULL } + }; + + + frauthstp = &frauthst; + ipsstp = &ipsst; + ifrstp = &ifrst; + fiop = &fio; + + *frfp = 0; + *fiopp = fiop; + *ipsstpp = ipsstp; + *ifrstpp = ifrstp; + *frauthstpp = frauthstp; + + bzero((char *)fiop, sizeof(*fiop)); + bzero((char *)ipsstp, sizeof(*ipsstp)); + bzero((char *)ifrstp, sizeof(*ifrstp)); + bzero((char *)frauthstp, sizeof(*frauthstp)); + + if (nlist(kernel, deadlist) == -1) { + fprintf(stderr, "nlist error\n"); + return; + } + + /* + * This is for SIOCGETFF. + */ + kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp)); + + /* + * f_locks is a combination of the lock variable from each part of + * ipfilter (state, auth, nat, fragments). + */ + kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop)); + kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value, + sizeof(fiop->f_locks[0])); + kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value, + sizeof(fiop->f_locks[1])); + kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value, + sizeof(fiop->f_locks[2])); + kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value, + sizeof(fiop->f_locks[3])); + + /* + * Get pointers to each list of rules (active, inactive, in, out) + */ + kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules)); + fiop->f_fin[0] = rules[0][0]; + fiop->f_fin[1] = rules[0][1]; + fiop->f_fout[0] = rules[1][0]; + fiop->f_fout[1] = rules[1][1]; + + /* + * Same for IPv6, except make them null if support for it is not + * being compiled in. + */ +#ifdef USE_INET6 + kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules)); + fiop->f_fin6[0] = rules[0][0]; + fiop->f_fin6[1] = rules[0][1]; + fiop->f_fout6[0] = rules[1][0]; + fiop->f_fout6[1] = rules[1][1]; +#else + fiop->f_fin6[0] = NULL; + fiop->f_fin6[1] = NULL; + fiop->f_fout6[0] = NULL; + fiop->f_fout6[1] = NULL; +#endif + + /* + * Now get accounting rules pointers. + */ + kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules)); + fiop->f_acctin[0] = rules[0][0]; + fiop->f_acctin[1] = rules[0][1]; + fiop->f_acctout[0] = rules[1][0]; + fiop->f_acctout[1] = rules[1][1]; + +#ifdef USE_INET6 + kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules)); + fiop->f_acctin6[0] = rules[0][0]; + fiop->f_acctin6[1] = rules[0][1]; + fiop->f_acctout6[0] = rules[1][0]; + fiop->f_acctout6[1] = rules[1][1]; +#else + fiop->f_acctin6[0] = NULL; + fiop->f_acctin6[1] = NULL; + fiop->f_acctout6[0] = NULL; + fiop->f_acctout6[1] = NULL; +#endif + + /* + * A collection of "global" variables used inside the kernel which + * are all collected in friostat_t via ioctl. + */ + kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value, + sizeof(fiop->f_froute)); + kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value, + sizeof(fiop->f_running)); + kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value, + sizeof(fiop->f_groups)); + kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value, + sizeof(fiop->f_active)); + kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value, + sizeof(fiop->f_defpass)); + + /* + * Build up the state information stats structure. + */ + kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp)); + kmemcpy((char *)&temp, (u_long)deadlist[15].n_value, sizeof(temp)); + ipsstp->iss_active = temp; + ipsstp->iss_table = (void *)deadlist[18].n_value; + ipsstp->iss_list = (void *)deadlist[17].n_value; + + /* + * Build up the authentiation information stats structure. + */ + kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value, + sizeof(*frauthstp)); + frauthstp->fas_faelist = (void *)deadlist[1].n_value; + + /* + * Build up the fragment information stats structure. + */ + kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value, + sizeof(*ifrstp)); + ifrstp->ifs_table = (void *)deadlist[23].n_value; + ifrstp->ifs_nattab = (void *)deadlist[24].n_value; + kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value, + sizeof(ifrstp->ifs_inuse)); + + /* + * Get logging on/off switches + */ + kmemcpy((char *)&state_logging, (u_long)deadlist[41].n_value, + sizeof(state_logging)); +} + + +/* + * Display the kernel stats for packets blocked and passed and other + * associated running totals which are kept. + */ +static void showstats(fp, frf) +struct friostat *fp; +u_32_t frf; +{ + + PRINTF("bad packets:\t\tin %lu\tout %lu\n", + fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); +#ifdef USE_INET6 + PRINTF(" IPv6 packets:\t\tin %lu out %lu\n", + fp->f_st[0].fr_ipv6, fp->f_st[1].fr_ipv6); +#endif + PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu", + fp->f_st[0].fr_block, fp->f_st[0].fr_pass, + fp->f_st[0].fr_nom); + PRINTF(" counted %lu short %lu\n", + fp->f_st[0].fr_acct, fp->f_st[0].fr_short); + PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu", + fp->f_st[1].fr_block, fp->f_st[1].fr_pass, + fp->f_st[1].fr_nom); + PRINTF(" counted %lu short %lu\n", + fp->f_st[1].fr_acct, fp->f_st[1].fr_short); + PRINTF(" input packets logged:\tblocked %lu passed %lu\n", + fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); + PRINTF("output packets logged:\tblocked %lu passed %lu\n", + fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); + PRINTF(" packets logged:\tinput %lu output %lu\n", + fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl); + PRINTF(" log failures:\t\tinput %lu output %lu\n", + fp->f_st[0].fr_skip, fp->f_st[1].fr_skip); + PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n", + fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr, + fp->f_st[0].fr_cfr); + PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n", + fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr, + fp->f_st[0].fr_cfr); + PRINTF("packet state(in):\tkept %lu\tlost %lu\n", + fp->f_st[0].fr_ads, fp->f_st[0].fr_bads); + PRINTF("packet state(out):\tkept %lu\tlost %lu\n", + fp->f_st[1].fr_ads, fp->f_st[1].fr_bads); + PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n", + fp->f_st[0].fr_ret, fp->f_st[1].fr_ret); + PRINTF("Invalid source(in):\t%lu\n", fp->f_st[0].fr_badsrc); + PRINTF("Result cache hits(in):\t%lu\t(out):\t%lu\n", + fp->f_st[0].fr_chit, fp->f_st[1].fr_chit); + PRINTF("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n", + fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]); + PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n", + fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]); + PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n", + fp->f_froute[0], fp->f_froute[1]); + PRINTF("TCP cksum fails(in):\t%lu\t(out):\t%lu\n", + fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad); + PRINTF("IPF Ticks:\t%lu\n", fp->f_ticks); + + PRINTF("Packet log flags set: (%#x)\n", frf); + if (frf & FF_LOGPASS) + PRINTF("\tpackets passed through filter\n"); + if (frf & FF_LOGBLOCK) + PRINTF("\tpackets blocked by filter\n"); + if (frf & FF_LOGNOMATCH) + PRINTF("\tpackets not matched by filter\n"); + if (!frf) + PRINTF("\tnone\n"); +} + + +/* + * Print out a list of rules from the kernel, starting at the one passed. + */ +static void printlist(fp, comment) +frentry_t *fp; +char *comment; +{ + struct frentry fb, *fg; + char *data; + u_32_t type; + int n; + + for (n = 1; fp; n++) { + if (kmemcpy((char *)&fb, (u_long)fp, sizeof(fb)) == -1) { + perror("kmemcpy"); + return; + } + fp = &fb; + if (opts & (OPT_HITS|OPT_VERBOSE)) +#ifdef USE_QUAD_T + PRINTF("%qu ", (unsigned long long) fp->fr_hits); +#else + PRINTF("%lu ", fp->fr_hits); +#endif + if (opts & (OPT_ACCNT|OPT_VERBOSE)) +#ifdef USE_QUAD_T + PRINTF("%qu ", (unsigned long long) fp->fr_bytes); +#else + PRINTF("%lu ", fp->fr_bytes); +#endif + if (opts & OPT_SHOWLINENO) + PRINTF("@%d ", n); + data = NULL; + type = fp->fr_type & ~FR_T_BUILTIN; + if (type == FR_T_IPF || type == FR_T_BPFOPC) { + if (fp->fr_dsize) { + data = malloc(fp->fr_dsize); + + if (kmemcpy(data, (u_long)fp->fr_data, + fp->fr_dsize) == -1) { + perror("kmemcpy"); + return; + } + fp->fr_data = data; + } + } + + printfr(fp, ioctl); + if (opts & OPT_DEBUG) { + binprint(fp, sizeof(*fp)); + if (fp->fr_data != NULL && fp->fr_dsize > 0) + binprint(fp->fr_data, fp->fr_dsize); + } + if (data != NULL) + free(data); + if (fp->fr_grp != NULL) { + if (!kmemcpy((char *)&fg, (u_long)fp->fr_grp, + sizeof(fg))) + printlist(fg, comment); + } + if (type == FR_T_CALLFUNC) { + printlist(fp->fr_data, "# callfunc: "); + } + fp = fp->fr_next; + } +} + +/* + * print out all of the asked for rule sets, using the stats struct as + * the base from which to get the pointers. + */ +static void showlist(fiop) +struct friostat *fiop; +{ + struct frentry *fp = NULL; + int i, set; + + set = fiop->f_active; + if (opts & OPT_INACTIVE) + set = 1 - set; + if (opts & OPT_ACCNT) { +#ifdef USE_INET6 + if ((use_inet6) && (opts & OPT_OUTQUE)) { + i = F_ACOUT; + fp = (struct frentry *)fiop->f_acctout6[set]; + } else if ((use_inet6) && (opts & OPT_INQUE)) { + i = F_ACIN; + fp = (struct frentry *)fiop->f_acctin6[set]; + } else +#endif + if (opts & OPT_OUTQUE) { + i = F_ACOUT; + fp = (struct frentry *)fiop->f_acctout[set]; + } else if (opts & OPT_INQUE) { + i = F_ACIN; + fp = (struct frentry *)fiop->f_acctin[set]; + } else { + FPRINTF(stderr, "No -i or -o given with -a\n"); + return; + } + } else { +#ifdef USE_INET6 + if ((use_inet6) && (opts & OPT_OUTQUE)) { + i = F_OUT; + fp = (struct frentry *)fiop->f_fout6[set]; + } else if ((use_inet6) && (opts & OPT_INQUE)) { + i = F_IN; + fp = (struct frentry *)fiop->f_fin6[set]; + } else +#endif + if (opts & OPT_OUTQUE) { + i = F_OUT; + fp = (struct frentry *)fiop->f_fout[set]; + } else if (opts & OPT_INQUE) { + i = F_IN; + fp = (struct frentry *)fiop->f_fin[set]; + } else + return; + } + if (opts & OPT_VERBOSE) + FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i); + + if (opts & OPT_VERBOSE) + PRINTF("fp %p set %d\n", fp, set); + if (!fp) { + FPRINTF(stderr, "empty list for %s%s\n", + (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); + return; + } + printlist(fp, NULL); +} + + +/* + * Display ipfilter stateful filtering information + */ +static void showipstates(ipsp) +ips_stat_t *ipsp; +{ + u_long minlen, maxlen, totallen, *buckets; + int i, sz; + + sz = sizeof(*buckets) * ipsp->iss_statesize; + buckets = (u_long *)malloc(sz); + if (kmemcpy((char *)buckets, (u_long)ipsp->iss_bucketlen, sz)) { + free(buckets); + return; + } + + /* + * If a list of states hasn't been asked for, only print out stats + */ + if (!(opts & OPT_SHOWLIST)) { + PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n", + ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp); + PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, + ipsp->iss_miss); + PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu max bucket\n", + ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_bucketfull); + PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\n", + ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse); + PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n", + ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin); + + PRINTF("State logging %sabled\n", + state_logging ? "en" : "dis"); + + PRINTF("\nState table bucket statistics:\n"); + PRINTF("\t%lu in use\t\n", ipsp->iss_inuse); + + minlen = ipsp->iss_max; + totallen = 0; + maxlen = 0; + + for (i = 0; i < ipsp->iss_statesize; i++) { + if (buckets[i] > maxlen) + maxlen = buckets[i]; + if (buckets[i] < minlen) + minlen = buckets[i]; + totallen += buckets[i]; + } + + PRINTF("\t%2.2f%% bucket usage\n\t%lu minimal length\n", + ((float)ipsp->iss_inuse / ipsp->iss_statesize) * 100.0, + minlen); + PRINTF("\t%lu maximal length\n\t%.3f average length\n", + maxlen, + ipsp->iss_inuse ? (float) totallen/ ipsp->iss_inuse : + 0.0); + +#define ENTRIES_PER_LINE 5 + + if (opts & OPT_VERBOSE) { + PRINTF("\nCurrent bucket sizes :\n"); + for (i = 0; i < ipsp->iss_statesize; i++) { + if ((i % ENTRIES_PER_LINE) == 0) + PRINTF("\t"); + PRINTF("%4d -> %4lu", i, buckets[i]); + if ((i % ENTRIES_PER_LINE) == + (ENTRIES_PER_LINE - 1)) + PRINTF("\n"); + else + PRINTF(" "); + } + PRINTF("\n"); + } + PRINTF("\n"); + + free(buckets); + return; + } + + /* + * Print out all the state information currently held in the kernel. + */ + while (ipsp->iss_list != NULL) { + ipsp->iss_list = printstate(ipsp->iss_list, opts, + ipsp->iss_ticks); + } + + free(buckets); +} + + +#ifdef STATETOP +static int handle_resize = 0, handle_break = 0; + +static void topipstates(saddr, daddr, sport, dport, protocol, ver, + refreshtime, topclosed) +i6addr_t saddr; +i6addr_t daddr; +int sport; +int dport; +int protocol; +int ver; +int refreshtime; +int topclosed; +{ + char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; + int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; + int i, j, winy, tsentry, maxx, maxy, redraw = 0; + int len, srclen, dstlen, forward = 1, c = 0; + ips_stat_t ipsst, *ipsstp = &ipsst; + statetop_t *tstable = NULL, *tp; + ipstate_t ips; + ipfobj_t ipfo; + struct timeval selecttimeout; + char hostnm[HOSTNMLEN]; + struct protoent *proto; + fd_set readfd; + time_t t; + + /* install signal handlers */ + signal(SIGINT, sig_break); + signal(SIGQUIT, sig_break); + signal(SIGTERM, sig_break); + signal(SIGWINCH, sig_resize); + + /* init ncurses stuff */ + initscr(); + cbreak(); + noecho(); + curs_set(0); + timeout(0); + getmaxyx(stdscr, maxy, maxx); + + /* init hostname */ + gethostname(hostnm, sizeof(hostnm) - 1); + hostnm[sizeof(hostnm) - 1] = '\0'; + + /* init ipfobj_t stuff */ + bzero((caddr_t)&ipfo, sizeof(ipfo)); + ipfo.ipfo_rev = IPFILTER_VERSION; + ipfo.ipfo_size = sizeof(*ipsstp); + ipfo.ipfo_ptr = (void *)ipsstp; + ipfo.ipfo_type = IPFOBJ_STATESTAT; + + /* repeat until user aborts */ + while ( 1 ) { + + /* get state table */ + bzero((char *)&ipsst, sizeof(ipsst)); + if ((ioctl(state_fd, SIOCGETFS, &ipfo) == -1)) { + perror("ioctl(SIOCGETFS)"); + exit(-1); + } + + /* clear the history */ + tsentry = -1; + + /* reset max str len */ + srclen = dstlen = 0; + + /* read the state table and store in tstable */ + for (; ipsstp->iss_list; ipsstp->iss_list = ips.is_next) { + + if (kmemcpy((char *)&ips, (u_long)ipsstp->iss_list, + sizeof(ips))) + break; + + if (ips.is_v != ver) + continue; + + /* check v4 src/dest addresses */ + if (ips.is_v == 4) { + if ((saddr.in4.s_addr != INADDR_ANY && + saddr.in4.s_addr != ips.is_saddr) || + (daddr.in4.s_addr != INADDR_ANY && + daddr.in4.s_addr != ips.is_daddr)) + continue; + } +#ifdef USE_INET6 + /* check v6 src/dest addresses */ + if (ips.is_v == 6) { + if ((IP6_NEQ(&saddr, &in6addr_any) && + IP6_NEQ(&saddr, &ips.is_src)) || + (IP6_NEQ(&daddr, &in6addr_any) && + IP6_NEQ(&daddr, &ips.is_dst))) + continue; + } +#endif + /* check protocol */ + if (protocol > 0 && protocol != ips.is_p) + continue; + + /* check ports if protocol is TCP or UDP */ + if (((ips.is_p == IPPROTO_TCP) || + (ips.is_p == IPPROTO_UDP)) && + (((sport > 0) && (htons(sport) != ips.is_sport)) || + ((dport > 0) && (htons(dport) != ips.is_dport)))) + continue; + + /* show closed TCP sessions ? */ + if ((topclosed == 0) && (ips.is_p == IPPROTO_TCP) && + (ips.is_state[0] >= IPF_TCPS_LAST_ACK) && + (ips.is_state[1] >= IPF_TCPS_LAST_ACK)) + continue; + + /* + * if necessary make room for this state + * entry + */ + tsentry++; + if (!maxtsentries || tsentry == maxtsentries) { + maxtsentries += STGROWSIZE; + tstable = realloc(tstable, + maxtsentries * sizeof(statetop_t)); + if (tstable == NULL) { + perror("realloc"); + exit(-1); + } + } + + /* get max src/dest address string length */ + len = strlen(getip(ips.is_v, &ips.is_src)); + if (srclen < len) + srclen = len; + len = strlen(getip(ips.is_v, &ips.is_dst)); + if (dstlen < len) + dstlen = len; + + /* fill structure */ + tp = tstable + tsentry; + tp->st_src = ips.is_src; + tp->st_dst = ips.is_dst; + tp->st_p = ips.is_p; + tp->st_v = ips.is_v; + tp->st_state[0] = ips.is_state[0]; + tp->st_state[1] = ips.is_state[1]; + if (forward) { + tp->st_pkts = ips.is_pkts[0]+ips.is_pkts[1]; + tp->st_bytes = ips.is_bytes[0]+ips.is_bytes[1]; + } else { + tp->st_pkts = ips.is_pkts[2]+ips.is_pkts[3]; + tp->st_bytes = ips.is_bytes[2]+ips.is_bytes[3]; + } + tp->st_age = ips.is_die - ipsstp->iss_ticks; + if ((ips.is_p == IPPROTO_TCP) || + (ips.is_p == IPPROTO_UDP)) { + tp->st_sport = ips.is_sport; + tp->st_dport = ips.is_dport; + } + } + + + /* sort the array */ + if (tsentry != -1) { + switch (sorting) + { + case STSORT_PR: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_p); + break; + case STSORT_PKTS: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_pkts); + break; + case STSORT_BYTES: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_bytes); + break; + case STSORT_TTL: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_ttl); + break; + case STSORT_SRCIP: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_srcip); + break; + case STSORT_SRCPT: + qsort(tstable, tsentry +1, + sizeof(statetop_t), sort_srcpt); + break; + case STSORT_DSTIP: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_dstip); + break; + case STSORT_DSTPT: + qsort(tstable, tsentry + 1, + sizeof(statetop_t), sort_dstpt); + break; + default: + break; + } + } + + /* handle window resizes */ + if (handle_resize) { + endwin(); + initscr(); + cbreak(); + noecho(); + curs_set(0); + timeout(0); + getmaxyx(stdscr, maxy, maxx); + redraw = 1; + handle_resize = 0; + } + + /* stop program? */ + if (handle_break) + break; + + /* print title */ + erase(); + attron(A_BOLD); + winy = 0; + move(winy,0); + sprintf(str1, "%s - %s - state top", hostnm, IPL_VERSION); + for (j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++) + printw(" "); + printw("%s", str1); + attroff(A_BOLD); + + /* just for fun add a clock */ + move(winy, maxx - 8); + t = time(NULL); + strftime(str1, 80, "%T", localtime(&t)); + printw("%s\n", str1); + + /* + * print the display filters, this is placed in the loop, + * because someday I might add code for changing these + * while the programming is running :-) + */ + if (sport >= 0) + sprintf(str1, "%s,%d", getip(ver, &saddr), sport); + else + sprintf(str1, "%s", getip(ver, &saddr)); + + if (dport >= 0) + sprintf(str2, "%s,%d", getip(ver, &daddr), dport); + else + sprintf(str2, "%s", getip(ver, &daddr)); + + if (protocol < 0) + strcpy(str3, "any"); + else if ((proto = getprotobynumber(protocol)) != NULL) + sprintf(str3, "%s", proto->p_name); + else + sprintf(str3, "%d", protocol); + + switch (sorting) + { + case STSORT_PR: + sprintf(str4, "proto"); + break; + case STSORT_PKTS: + sprintf(str4, "# pkts"); + break; + case STSORT_BYTES: + sprintf(str4, "# bytes"); + break; + case STSORT_TTL: + sprintf(str4, "ttl"); + break; + case STSORT_SRCIP: + sprintf(str4, "src ip"); + break; + case STSORT_SRCPT: + sprintf(str4, "src port"); + break; + case STSORT_DSTIP: + sprintf(str4, "dest ip"); + break; + case STSORT_DSTPT: + sprintf(str4, "dest port"); + break; + default: + sprintf(str4, "unknown"); + break; + } + + if (reverse) + strcat(str4, " (reverse)"); + + winy += 2; + move(winy,0); + printw("Src: %s, Dest: %s, Proto: %s, Sorted by: %s\n\n", + str1, str2, str3, str4); + + /* + * For an IPv4 IP address we need at most 15 characters, + * 4 tuples of 3 digits, separated by 3 dots. Enforce this + * length, so the colums do not change positions based + * on the size of the IP address. This length makes the + * output fit in a 80 column terminal. + * We are lacking a good solution for IPv6 addresses (that + * can be longer that 15 characters), so we do not enforce + * a maximum on the IP field size. + */ + if (srclen < 15) + srclen = 15; + if (dstlen < 15) + dstlen = 15; + + /* print column description */ + winy += 2; + move(winy,0); + attron(A_BOLD); + printw("%-*s %-*s %3s %4s %7s %9s %9s\n", + srclen + 6, "Source IP", dstlen + 6, "Destination IP", + "ST", "PR", "#pkts", "#bytes", "ttl"); + attroff(A_BOLD); + + /* print all the entries */ + tp = tstable; + if (reverse) + tp += tsentry; + + if (tsentry > maxy - 6) + tsentry = maxy - 6; + for (i = 0; i <= tsentry; i++) { + /* print src/dest and port */ + if ((tp->st_p == IPPROTO_TCP) || + (tp->st_p == IPPROTO_UDP)) { + sprintf(str1, "%s,%hu", + getip(tp->st_v, &tp->st_src), + ntohs(tp->st_sport)); + sprintf(str2, "%s,%hu", + getip(tp->st_v, &tp->st_dst), + ntohs(tp->st_dport)); + } else { + sprintf(str1, "%s", getip(tp->st_v, + &tp->st_src)); + sprintf(str2, "%s", getip(tp->st_v, + &tp->st_dst)); + } + winy++; + move(winy, 0); + printw("%-*s %-*s", srclen + 6, str1, dstlen + 6, str2); + + /* print state */ + sprintf(str1, "%X/%X", tp->st_state[0], + tp->st_state[1]); + printw(" %3s", str1); + + /* print protocol */ + proto = getprotobynumber(tp->st_p); + if (proto) { + strncpy(str1, proto->p_name, 4); + str1[4] = '\0'; + } else { + sprintf(str1, "%d", tp->st_p); + } + /* just print icmp for IPv6-ICMP */ + if (tp->st_p == IPPROTO_ICMPV6) + strcpy(str1, "icmp"); + printw(" %4s", str1); + + /* print #pkt/#bytes */ +#ifdef USE_QUAD_T + printw(" %7qu %9qu", (unsigned long long) tp->st_pkts, + (unsigned long long) tp->st_bytes); +#else + printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes); +#endif + printw(" %9s", ttl_to_string(tp->st_age)); + + if (reverse) + tp--; + else + tp++; + } + + /* screen data structure is filled, now update the screen */ + if (redraw) + clearok(stdscr,1); + + if (refresh() == ERR) + break; + if (redraw) { + clearok(stdscr,0); + redraw = 0; + } + + /* wait for key press or a 1 second time out period */ + selecttimeout.tv_sec = refreshtime; + selecttimeout.tv_usec = 0; + FD_ZERO(&readfd); + FD_SET(0, &readfd); + select(1, &readfd, NULL, NULL, &selecttimeout); + + /* if key pressed, read all waiting keys */ + if (FD_ISSET(0, &readfd)) { + c = wgetch(stdscr); + if (c == ERR) + continue; + + if (ISALPHA(c) && ISUPPER(c)) + c = TOLOWER(c); + if (c == 'l') { + redraw = 1; + } else if (c == 'q') { + break; + } else if (c == 'r') { + reverse = !reverse; + } else if (c == 'b') { + forward = 0; + } else if (c == 'f') { + forward = 1; + } else if (c == 's') { + if (++sorting > STSORT_MAX) + sorting = 0; + } + } + } /* while */ + + printw("\n"); + curs_set(1); + nocbreak(); + endwin(); + + free(tstable); +} +#endif + + +/* + * Show fragment cache information that's held in the kernel. + */ +static void showfrstates(ifsp) +ipfrstat_t *ifsp; +{ + struct ipfr *ipfrtab[IPFT_SIZE], ifr; + int i; + + /* + * print out the numeric statistics + */ + PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n", + ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits); + PRINTF("\t%lu retrans\n\t%lu too short\n", + ifsp->ifs_retrans0, ifsp->ifs_short); + PRINTF("\t%lu no memory\n\t%lu already exist\n", + ifsp->ifs_nomem, ifsp->ifs_exists); + PRINTF("\t%lu inuse\n", ifsp->ifs_inuse); + if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab))) + return; + + /* + * Print out the contents (if any) of the fragment cache table. + */ + PRINTF("\n"); + for (i = 0; i < IPFT_SIZE; i++) + while (ipfrtab[i] != NULL) { + if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], + sizeof(ifr)) == -1) + break; + printfraginfo("", &ifr); + ipfrtab[i] = ifr.ipfr_next; + } + /* + * Print out the contents (if any) of the NAT fragment cache table. + */ + if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab))) + return; + for (i = 0; i < IPFT_SIZE; i++) + while (ipfrtab[i] != NULL) { + if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], + sizeof(ifr)) == -1) + break; + printfraginfo("NAT: ", &ifr); + ipfrtab[i] = ifr.ipfr_next; + } +} + + +/* + * Show stats on how auth within IPFilter has been used + */ +static void showauthstates(asp) +fr_authstat_t *asp; +{ + frauthent_t *frap, fra; + +#ifdef USE_QUAD_T + printf("Authorisation hits: %qu\tmisses %qu\n", + (unsigned long long) asp->fas_hits, + (unsigned long long) asp->fas_miss); +#else + printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, + asp->fas_miss); +#endif + printf("nospace %ld\nadded %ld\nsendfail %ld\nsendok %ld\n", + asp->fas_nospace, asp->fas_added, asp->fas_sendfail, + asp->fas_sendok); + printf("queok %ld\nquefail %ld\nexpire %ld\n", + asp->fas_queok, asp->fas_quefail, asp->fas_expire); + + frap = asp->fas_faelist; + while (frap) { + if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1) + break; + + printf("age %ld\t", fra.fae_age); + printfr(&fra.fae_fr, ioctl); + frap = fra.fae_next; + } +} + + +/* + * Display groups used for each of filter rules, accounting rules and + * authentication, separately. + */ +static void showgroups(fiop) +struct friostat *fiop; +{ + static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; + static int gnums[3] = { IPL_LOGIPF, IPL_LOGCOUNT, IPL_LOGAUTH }; + frgroup_t *fp, grp; + int on, off, i; + + on = fiop->f_active; + off = 1 - on; + + for (i = 0; i < 3; i++) { + printf("%s groups (active):\n", gnames[i]); + for (fp = fiop->f_groups[gnums[i]][on]; fp != NULL; + fp = grp.fg_next) + if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) + break; + else + printf("%s\n", grp.fg_name); + printf("%s groups (inactive):\n", gnames[i]); + for (fp = fiop->f_groups[gnums[i]][off]; fp != NULL; + fp = grp.fg_next) + if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) + break; + else + printf("%s\n", grp.fg_name); + } +} + +static void parse_ipportstr(argument, ip, port) +const char *argument; +i6addr_t *ip; +int *port; +{ + char *s, *comma; + int ok = 0; + + /* make working copy of argument, Theoretically you must be able + * to write to optarg, but that seems very ugly to me.... + */ + s = strdup(argument); + if (s == NULL) + return; + + /* get port */ + if ((comma = strchr(s, ',')) != NULL) { + if (!strcasecmp(comma + 1, "any")) { + *port = -1; + } else if (!sscanf(comma + 1, "%d", port) || + (*port < 0) || (*port > 65535)) { + fprintf(stderr, "Invalid port specfication in %s\n", + argument); + free(s); + exit(-2); + } + *comma = '\0'; + } + + + /* get ip address */ + if (!strcasecmp(s, "any")) { + ip->in4.s_addr = INADDR_ANY; +#ifdef USE_INET6 + ip->in6 = in6addr_any; + } else if (use_inet6 && inet_pton(AF_INET6, s, &ip->in6)) { + ok = 1; +#endif + } else if (inet_aton(s, &ip->in4)) + ok = 1; + + if (ok == 0) { + fprintf(stderr, "Invalid IP address: %s\n", s); + free(s); + exit(-2); + } + + /* free allocated memory */ + free(s); +} + + +#ifdef STATETOP +static void sig_resize(s) +int s; +{ + handle_resize = 1; +} + +static void sig_break(s) +int s; +{ + handle_break = 1; +} + +static char *getip(v, addr) +int v; +i6addr_t *addr; +{ + static char hostbuf[MAXHOSTNAMELEN+1]; + + if (v == 4) + return inet_ntoa(addr->in4); + +#ifdef USE_INET6 + (void) inet_ntop(AF_INET6, &addr->in6, hostbuf, sizeof(hostbuf) - 1); + hostbuf[MAXHOSTNAMELEN] = '\0'; + return hostbuf; +#else + return "IPv6"; +#endif +} + + +static char *ttl_to_string(ttl) +long int ttl; +{ + static char ttlbuf[STSTRSIZE]; + int hours, minutes, seconds; + + /* ttl is in half seconds */ + ttl /= 2; + + hours = ttl / 3600; + ttl = ttl % 3600; + minutes = ttl / 60; + seconds = ttl % 60; + + if (hours > 0) + sprintf(ttlbuf, "%2d:%02d:%02d", hours, minutes, seconds); + else + sprintf(ttlbuf, "%2d:%02d", minutes, seconds); + return ttlbuf; +} + + +static int sort_pkts(a, b) +const void *a; +const void *b; +{ + + register const statetop_t *ap = a; + register const statetop_t *bp = b; + + if (ap->st_pkts == bp->st_pkts) + return 0; + else if (ap->st_pkts < bp->st_pkts) + return 1; + return -1; +} + + +static int sort_bytes(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + + if (ap->st_bytes == bp->st_bytes) + return 0; + else if (ap->st_bytes < bp->st_bytes) + return 1; + return -1; +} + + +static int sort_p(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + + if (ap->st_p == bp->st_p) + return 0; + else if (ap->st_p < bp->st_p) + return 1; + return -1; +} + + +static int sort_ttl(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + + if (ap->st_age == bp->st_age) + return 0; + else if (ap->st_age < bp->st_age) + return 1; + return -1; +} + +static int sort_srcip(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + +#ifdef USE_INET6 + if (use_inet6) { + if (IP6_EQ(&ap->st_src, &bp->st_src)) + return 0; + else if (IP6_GT(&ap->st_src, &bp->st_src)) + return 1; + } else +#endif + { + if (ntohl(ap->st_src.in4.s_addr) == + ntohl(bp->st_src.in4.s_addr)) + return 0; + else if (ntohl(ap->st_src.in4.s_addr) > + ntohl(bp->st_src.in4.s_addr)) + return 1; + } + return -1; +} + +static int sort_srcpt(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + + if (htons(ap->st_sport) == htons(bp->st_sport)) + return 0; + else if (htons(ap->st_sport) > htons(bp->st_sport)) + return 1; + return -1; +} + +static int sort_dstip(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + +#ifdef USE_INET6 + if (use_inet6) { + if (IP6_EQ(&ap->st_dst, &bp->st_dst)) + return 0; + else if (IP6_GT(&ap->st_dst, &bp->st_dst)) + return 1; + } else +#endif + { + if (ntohl(ap->st_dst.in4.s_addr) == + ntohl(bp->st_dst.in4.s_addr)) + return 0; + else if (ntohl(ap->st_dst.in4.s_addr) > + ntohl(bp->st_dst.in4.s_addr)) + return 1; + } + return -1; +} + +static int sort_dstpt(a, b) +const void *a; +const void *b; +{ + register const statetop_t *ap = a; + register const statetop_t *bp = b; + + if (htons(ap->st_dport) == htons(bp->st_dport)) + return 0; + else if (htons(ap->st_dport) > htons(bp->st_dport)) + return 1; + return -1; +} + +#endif diff --git a/contrib/ipfilter/tools/ipftest.c b/contrib/ipfilter/tools/ipftest.c new file mode 100644 index 000000000000..fbc91e5aae66 --- /dev/null +++ b/contrib/ipfilter/tools/ipftest.c @@ -0,0 +1,776 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#include "ipf.h" +#include "ipt.h" +#include +#include + +#if !defined(lint) +static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipftest.c,v 1.44.2.3 2005/02/01 02:41:24 darrenr Exp"; +#endif + +extern char *optarg; +extern struct frentry *ipfilter[2][2]; +extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex; +extern struct ifnet *get_unit __P((char *, int)); +extern void init_ifp __P((void)); +extern ipnat_t *natparse __P((char *, int)); +extern int fr_running; + +ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert; +ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; +ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag, ip_poolrw; +ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; +int opts = OPT_DONOTHING; +int use_inet6 = 0; +int pfil_delayed_copy = 0; +int main __P((int, char *[])); +int loadrules __P((char *, int)); +int kmemcpy __P((char *, long, int)); +int kstrncpy __P((char *, long, int n)); +void dumpnat __P((void)); +void dumpstate __P((void)); +void dumplookups __P((void)); +void dumpgroups __P((void)); +void drain_log __P((char *)); +void fixv4sums __P((mb_t *, ip_t *)); + +#if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \ + (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \ + defined(__osf__) || defined(linux) +int ipftestioctl __P((int, ioctlcmd_t, ...)); +int ipnattestioctl __P((int, ioctlcmd_t, ...)); +int ipstatetestioctl __P((int, ioctlcmd_t, ...)); +int ipauthtestioctl __P((int, ioctlcmd_t, ...)); +int ipscantestioctl __P((int, ioctlcmd_t, ...)); +int ipsynctestioctl __P((int, ioctlcmd_t, ...)); +int ipooltestioctl __P((int, ioctlcmd_t, ...)); +#else +int ipftestioctl __P((dev_t, ioctlcmd_t, void *)); +int ipnattestioctl __P((dev_t, ioctlcmd_t, void *)); +int ipstatetestioctl __P((dev_t, ioctlcmd_t, void *)); +int ipauthtestioctl __P((dev_t, ioctlcmd_t, void *)); +int ipsynctestioctl __P((dev_t, ioctlcmd_t, void *)); +int ipscantestioctl __P((dev_t, ioctlcmd_t, void *)); +int ipooltestioctl __P((dev_t, ioctlcmd_t, void *)); +#endif + +static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ipftestioctl, + ipnattestioctl, + ipstatetestioctl, + ipauthtestioctl, + ipsynctestioctl, + ipscantestioctl, + ipooltestioctl, + NULL }; + + +int main(argc,argv) +int argc; +char *argv[]; +{ + char *datain, *iface, *ifname, *logout; + int fd, i, dir, c, loaded, dump, hlen; + struct ifnet *ifp; + struct ipread *r; + mb_t mb, *m; + ip_t *ip; + + m = &mb; + dir = 0; + dump = 0; + hlen = 0; + loaded = 0; + r = &iptext; + iface = NULL; + logout = NULL; + ifname = "anon0"; + datain = NULL; + + MUTEX_INIT(&ipf_rw, "ipf rw mutex"); + MUTEX_INIT(&ipf_timeoutlock, "ipf timeout lock"); + RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); + RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); + RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); + + initparse(); + if (fr_initialise() == -1) + abort(); + fr_running = 1; + + while ((c = getopt(argc, argv, "6bdDF:i:I:l:N:P:or:RT:vxX")) != -1) + switch (c) + { + case '6' : +#ifdef USE_INET6 + use_inet6 = 1; +#else + fprintf(stderr, "IPv6 not supported\n"); + exit(1); +#endif + break; + case 'b' : + opts |= OPT_BRIEF; + break; + case 'd' : + opts |= OPT_DEBUG; + break; + case 'D' : + dump = 1; + break; + case 'F' : + if (strcasecmp(optarg, "pcap") == 0) + r = &pcap; + else if (strcasecmp(optarg, "etherfind") == 0) + r = ðerf; + else if (strcasecmp(optarg, "snoop") == 0) + r = &snoop; + else if (strcasecmp(optarg, "tcpdump") == 0) + r = &tcpd; + else if (strcasecmp(optarg, "hex") == 0) + r = &iphex; + else if (strcasecmp(optarg, "text") == 0) + r = &iptext; + break; + case 'i' : + datain = optarg; + break; + case 'I' : + ifname = optarg; + break; + case 'l' : + logout = optarg; + break; + case 'o' : + opts |= OPT_SAVEOUT; + break; + case 'r' : + if (ipf_parsefile(-1, ipf_addrule, iocfunctions, + optarg) == -1) + return -1; + loaded = 1; + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + case 'N' : + if (ipnat_parsefile(-1, ipnat_addrule, ipnattestioctl, + optarg) == -1) + return -1; + loaded = 1; + opts |= OPT_NAT; + break; + case 'P' : + if (ippool_parsefile(-1, optarg, ipooltestioctl) == -1) + return -1; + loaded = 1; + break; + case 'T' : + ipf_dotuning(-1, optarg, ipftestioctl); + break; + case 'x' : + opts |= OPT_HEX; + break; + } + + if (loaded == 0) { + (void)fprintf(stderr,"no rules loaded\n"); + exit(-1); + } + + if (opts & OPT_SAVEOUT) + init_ifp(); + + if (datain) + fd = (*r->r_open)(datain); + else + fd = (*r->r_open)("-"); + + if (fd < 0) + exit(-1); + + ip = MTOD(m, ip_t *); + while ((i = (*r->r_readip)(MTOD(m, char *), sizeof(m->mb_buf), + &iface, &dir)) > 0) { + if (iface == NULL || *iface == '\0') + iface = ifname; + ifp = get_unit(iface, IP_V(ip)); + if (!use_inet6) { + ip->ip_off = ntohs(ip->ip_off); + ip->ip_len = ntohs(ip->ip_len); + if (r->r_flags & R_DO_CKSUM) + fixv4sums(m, ip); + hlen = IP_HL(ip) << 2; + } +#ifdef USE_INET6 + else + hlen = sizeof(ip6_t); +#endif + /* ipfr_slowtimer(); */ + m = &mb; + m->mb_len = i; + i = fr_check(ip, hlen, ifp, dir, &m); + if ((opts & OPT_NAT) == 0) + switch (i) + { + case -4 : + (void)printf("preauth"); + break; + case -3 : + (void)printf("account"); + break; + case -2 : + (void)printf("auth"); + break; + case -1 : + (void)printf("block"); + break; + case 0 : + (void)printf("pass"); + break; + case 1 : + (void)printf("nomatch"); + break; + case 3 : + (void)printf("block return-rst"); + break; + case 4 : + (void)printf("block return-icmp"); + break; + case 5 : + (void)printf("block return-icmp-as-dest"); + break; + default : + (void)printf("recognised return %#x\n", i); + break; + } + if (!use_inet6) { + ip->ip_off = htons(ip->ip_off); + ip->ip_len = htons(ip->ip_len); + } + + if (!(opts & OPT_BRIEF)) { + putchar(' '); + printpacket(ip); + printf("--------------"); + } else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF)) + printpacket(ip); + if (dir && (ifp != NULL) && IP_V(ip) && (m != NULL)) +#if defined(__sgi) && (IRIX < 60500) + (*ifp->if_output)(ifp, (void *)m, NULL); +#else +# if TRU64 >= 1885 + (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); +# else + (*ifp->if_output)(ifp, (void *)m, NULL, 0); +# endif +#endif + if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF)) + putchar('\n'); + dir = 0; + if (iface != ifname) { + free(iface); + iface = ifname; + } + m = &mb; + } + (*r->r_close)(); + + if (logout != NULL) { + drain_log(logout); + } + + if (dump == 1) { + dumpnat(); + dumpstate(); + dumplookups(); + dumpgroups(); + } + + fr_deinitialise(); + + return 0; +} + + +#if defined(__NetBSD__) || defined(__OpenBSD__) || SOLARIS || \ + (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) || \ + defined(__osf__) || defined(linux) +int ipftestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD); + if (opts & OPT_DEBUG) + fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipnattestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD); + if (opts & OPT_DEBUG) + fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipstatetestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipauthtestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipscantestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipsynctestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipooltestioctl(int dev, ioctlcmd_t cmd, ...) +{ + caddr_t data; + va_list ap; + int i; + + va_start(ap, cmd); + data = va_arg(ap, caddr_t); + va_end(ap); + + i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", + (u_int)cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} +#else +int ipftestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGIPF, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(IPF,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipnattestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGNAT, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(NAT,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipstatetestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGSTATE, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(STATE,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipauthtestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGAUTH, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(AUTH,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipsynctestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGSYNC, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(SYNC,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipscantestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGSCAN, cmd, data, FWRITE|FREAD); + if ((opts & OPT_DEBUG) || (i != 0)) + fprintf(stderr, "iplioctl(SCAN,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} + + +int ipooltestioctl(dev, cmd, data) +dev_t dev; +ioctlcmd_t cmd; +void *data; +{ + int i; + + i = iplioctl(IPL_LOGLOOKUP, cmd, data, FWRITE|FREAD); + if (opts & OPT_DEBUG) + fprintf(stderr, "iplioctl(POOL,%#x,%p) = %d\n", cmd, data, i); + if (i != 0) { + errno = i; + return -1; + } + return 0; +} +#endif + + +int kmemcpy(addr, offset, size) +char *addr; +long offset; +int size; +{ + bcopy((char *)offset, addr, size); + return 0; +} + + +int kstrncpy(buf, pos, n) +char *buf; +long pos; +int n; +{ + char *ptr; + + ptr = (char *)pos; + + while ((n > 0) && (*buf++ = *ptr++)) + ; + return 0; +} + + +/* + * Display the built up NAT table rules and mapping entries. + */ +void dumpnat() +{ + ipnat_t *ipn; + nat_t *nat; + + printf("List of active MAP/Redirect filters:\n"); + for (ipn = nat_list; ipn != NULL; ipn = ipn->in_next) + printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); + printf("\nList of active sessions:\n"); + for (nat = nat_instances; nat; nat = nat->nat_next) { + printactivenat(nat, opts); + if (nat->nat_aps) + printaps(nat->nat_aps, opts); + } +} + + +/* + * Display the built up state table rules and mapping entries. + */ +void dumpstate() +{ + ipstate_t *ips; + + printf("List of active state sessions:\n"); + for (ips = ips_list; ips != NULL; ) + ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE), + fr_ticks); +} + + +void dumplookups() +{ + iphtable_t *iph; + ip_pool_t *ipl; + int i; + + printf("List of configured pools\n"); + for (i = 0; i < IPL_LOGSIZE; i++) + for (ipl = ip_pool_list[i]; ipl != NULL; ipl = ipl->ipo_next) + printpool(ipl, bcopywrap, NULL, opts); + + printf("List of configured hash tables\n"); + for (i = 0; i < IPL_LOGSIZE; i++) + for (iph = ipf_htables[i]; iph != NULL; iph = iph->iph_next) + printhash(iph, bcopywrap, NULL, opts); +} + + +void dumpgroups() +{ + frgroup_t *fg; + frentry_t *fr; + int i; + + printf("List of groups configured (set 0)\n"); + for (i = 0; i < IPL_LOGSIZE; i++) + for (fg = ipfgroups[i][0]; fg != NULL; fg = fg->fg_next) { + printf("Dev.%d. Group %s Ref %d Flags %#x\n", + i, fg->fg_name, fg->fg_ref, fg->fg_flags); + for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) { +#ifdef USE_QUAD_T + printf("%qu ",(unsigned long long)fr->fr_hits); +#else + printf("%ld ", fr->fr_hits); +#endif + printfr(fr, ipftestioctl); + } + } + + printf("List of groups configured (set 1)\n"); + for (i = 0; i < IPL_LOGSIZE; i++) + for (fg = ipfgroups[i][1]; fg != NULL; fg = fg->fg_next) { + printf("Dev.%d. Group %s Ref %d Flags %#x\n", + i, fg->fg_name, fg->fg_ref, fg->fg_flags); + for (fr = fg->fg_start; fr != NULL; fr = fr->fr_next) { +#ifdef USE_QUAD_T + printf("%qu ",(unsigned long long)fr->fr_hits); +#else + printf("%ld ", fr->fr_hits); +#endif + printfr(fr, ipftestioctl); + } + } +} + + +void drain_log(filename) +char *filename; +{ + char buffer[DEFAULT_IPFLOGSIZE]; + struct iovec iov; + struct uio uio; + size_t resid; + int fd, i; + + fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); + if (fd == -1) { + perror("drain_log:open"); + return; + } + + for (i = 0; i <= IPL_LOGMAX; i++) + while (1) { + bzero((char *)&iov, sizeof(iov)); + iov.iov_base = buffer; + iov.iov_len = sizeof(buffer); + + bzero((char *)&uio, sizeof(uio)); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = iov.iov_len; + resid = uio.uio_resid; + + if (ipflog_read(i, &uio) == 0) { + /* + * If nothing was read then break out. + */ + if (uio.uio_resid == resid) + break; + write(fd, buffer, resid - uio.uio_resid); + } else + break; + } + + close(fd); +} + + +void fixv4sums(m, ip) +mb_t *m; +ip_t *ip; +{ + u_char *csump, *hdr; + + ip->ip_sum = 0; + ip->ip_sum = ipf_cksum((u_short *)ip, IP_HL(ip) << 2); + + csump = (u_char *)ip; + csump += IP_HL(ip) << 2; + + switch (ip->ip_p) + { + case IPPROTO_TCP : + hdr = csump; + csump += offsetof(tcphdr_t, th_sum); + break; + case IPPROTO_UDP : + hdr = csump; + csump += offsetof(udphdr_t, uh_sum); + break; + default : + csump = NULL; + hdr = NULL; + break; + } + if (hdr != NULL) { + *csump = 0; + *(u_short *)csump = fr_cksum(m, ip, ip->ip_p, hdr); + } +} diff --git a/contrib/ipfilter/tools/ipmon.c b/contrib/ipfilter/tools/ipmon.c new file mode 100644 index 000000000000..a91eee455d46 --- /dev/null +++ b/contrib/ipfilter/tools/ipmon.c @@ -0,0 +1,1663 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001, 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#ifndef SOLARIS +#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun) +#endif + +#include +#include +#include +#include +#include +#define _KERNEL +#include +#undef _KERNEL +#include +#include + +#include +#include +#include +#include +#include +#include +#if !defined(__SVR4) && !defined(__svr4__) +# if (__FreeBSD_version >= 300000) +# include +# else +# include +# endif +#else +# include +# include +#endif +#if !defined(__hpux) && (!defined(__SVR4) && !defined(__GNUC__)) +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#if !defined(__hpux) && !defined(linux) +# include +#endif +#include +#include +#include +#ifdef __hpux +# undef NOERROR +#endif +#include + +#if !defined(linux) +# include +# include +#endif + +#include +#include + +#include +#include + +#include "netinet/ip_compat.h" +#include +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_state.h" +#include "netinet/ip_proxy.h" +#include "ipmon.h" + +#if !defined(lint) +static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipmon.c,v 1.33.2.8 2004/12/09 19:41:26 darrenr Exp"; +#endif + + +#if defined(sun) && !defined(SOLARIS2) +#define STRERROR(x) sys_errlist[x] +extern char *sys_errlist[]; +#else +#define STRERROR(x) strerror(x) +#endif + + +struct flags { + int value; + char flag; +}; + + +typedef struct icmp_subtype { + int ist_val; + char *ist_name; +} icmp_subtype_t; + +typedef struct icmp_type { + int it_val; + struct icmp_subtype *it_subtable; + size_t it_stsize; + char *it_name; +} icmp_type_t; + + +#define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t)) + + +struct flags tcpfl[] = { + { TH_ACK, 'A' }, + { TH_RST, 'R' }, + { TH_SYN, 'S' }, + { TH_FIN, 'F' }, + { TH_URG, 'U' }, + { TH_PUSH,'P' }, + { TH_ECN, 'E' }, + { TH_CWR, 'C' }, + { 0, '\0' } +}; + +#ifdef MENTAT +static char *pidfile = "/etc/opt/ipf/ipmon.pid"; +#else +# if BSD >= 199306 +static char *pidfile = "/var/run/ipmon.pid"; +# else +static char *pidfile = "/etc/ipmon.pid"; +# endif +#endif + +static char line[2048]; +static int opts = 0; +static char *logfile = NULL; +static FILE *binarylog = NULL; +static char *binarylogfile = NULL; +static int donehup = 0; +static void usage __P((char *)); +static void handlehup __P((int)); +static void flushlogs __P((char *, FILE *)); +static void print_log __P((int, FILE *, char *, int)); +static void print_ipflog __P((FILE *, char *, int)); +static void print_natlog __P((FILE *, char *, int)); +static void print_statelog __P((FILE *, char *, int)); +static int read_log __P((int, int *, char *, int)); +static void write_pid __P((char *)); +static char *icmpname __P((u_int, u_int)); +static char *icmpname6 __P((u_int, u_int)); +static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t)); +static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t)); +#ifdef __hpux +static struct tm *get_tm __P((u_32_t)); +#else +static struct tm *get_tm __P((time_t)); +#endif + +char *hostname __P((int, int, u_32_t *)); +char *portname __P((int, char *, u_int)); +int main __P((int, char *[])); + +static void logopts __P((int, char *)); +static void init_tabs __P((void)); +static char *getproto __P((u_int)); + +static char **protocols = NULL; +static char **udp_ports = NULL; +static char **tcp_ports = NULL; +static char *conf_file = NULL; + + +#define OPT_SYSLOG 0x001 +#define OPT_RESOLVE 0x002 +#define OPT_HEXBODY 0x004 +#define OPT_VERBOSE 0x008 +#define OPT_HEXHDR 0x010 +#define OPT_TAIL 0x020 +#define OPT_NAT 0x080 +#define OPT_STATE 0x100 +#define OPT_FILTER 0x200 +#define OPT_PORTNUM 0x400 +#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) +#define OPT_LOGBODY 0x800 + +#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) + +#ifndef LOGFAC +#define LOGFAC LOG_LOCAL0 +#endif + + +static icmp_subtype_t icmpunreachnames[] = { + { ICMP_UNREACH_NET, "net" }, + { ICMP_UNREACH_HOST, "host" }, + { ICMP_UNREACH_PROTOCOL, "protocol" }, + { ICMP_UNREACH_PORT, "port" }, + { ICMP_UNREACH_NEEDFRAG, "needfrag" }, + { ICMP_UNREACH_SRCFAIL, "srcfail" }, + { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" }, + { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" }, + { ICMP_UNREACH_NET, "isolated" }, + { ICMP_UNREACH_NET_PROHIB, "net_prohib" }, + { ICMP_UNREACH_NET_PROHIB, "host_prohib" }, + { ICMP_UNREACH_TOSNET, "tosnet" }, + { ICMP_UNREACH_TOSHOST, "toshost" }, + { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" }, + { -2, NULL } +}; + +static icmp_subtype_t redirectnames[] = { + { ICMP_REDIRECT_NET, "net" }, + { ICMP_REDIRECT_HOST, "host" }, + { ICMP_REDIRECT_TOSNET, "tosnet" }, + { ICMP_REDIRECT_TOSHOST, "toshost" }, + { -2, NULL } +}; + +static icmp_subtype_t timxceednames[] = { + { ICMP_TIMXCEED_INTRANS, "transit" }, + { ICMP_TIMXCEED_REASS, "reassem" }, + { -2, NULL } +}; + +static icmp_subtype_t paramnames[] = { + { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" }, + { ICMP_PARAMPROB_OPTABSENT, "optmissing" }, + { ICMP_PARAMPROB_LENGTH, "length" }, + { -2, NULL } +}; + +static icmp_type_t icmptypes[] = { + { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, + { -1, NULL, 0, NULL }, + { -1, NULL, 0, NULL }, + { ICMP_UNREACH, icmpunreachnames, + IST_SZ(icmpunreachnames),"unreach" }, + { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" }, + { ICMP_REDIRECT, redirectnames, + IST_SZ(redirectnames), "redirect" }, + { -1, NULL, 0, NULL }, + { -1, NULL, 0, NULL }, + { ICMP_ECHO, NULL, 0, "echo" }, + { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" }, + { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" }, + { ICMP_TIMXCEED, timxceednames, + IST_SZ(timxceednames), "timxceed" }, + { ICMP_PARAMPROB, paramnames, + IST_SZ(paramnames), "paramprob" }, + { ICMP_TSTAMP, NULL, 0, "timestamp" }, + { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" }, + { ICMP_IREQ, NULL, 0, "inforeq" }, + { ICMP_IREQREPLY, NULL, 0, "inforeply" }, + { ICMP_MASKREQ, NULL, 0, "maskreq" }, + { ICMP_MASKREPLY, NULL, 0, "maskreply" }, + { -2, NULL, 0, NULL } +}; + +static icmp_subtype_t icmpredirect6[] = { + { ICMP6_DST_UNREACH_NOROUTE, "noroute" }, + { ICMP6_DST_UNREACH_ADMIN, "admin" }, + { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" }, + { ICMP6_DST_UNREACH_ADDR, "address" }, + { ICMP6_DST_UNREACH_NOPORT, "noport" }, + { -2, NULL } +}; + +static icmp_subtype_t icmptimexceed6[] = { + { ICMP6_TIME_EXCEED_TRANSIT, "intransit" }, + { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" }, + { -2, NULL } +}; + +static icmp_subtype_t icmpparamprob6[] = { + { ICMP6_PARAMPROB_HEADER, "header" }, + { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" }, + { ICMP6_PARAMPROB_OPTION, "option" }, + { -2, NULL } +}; + +static icmp_subtype_t icmpquerysubject6[] = { + { ICMP6_NI_SUBJ_IPV6, "ipv6" }, + { ICMP6_NI_SUBJ_FQDN, "fqdn" }, + { ICMP6_NI_SUBJ_IPV4, "ipv4" }, + { -2, NULL }, +}; + +static icmp_subtype_t icmpnodeinfo6[] = { + { ICMP6_NI_SUCCESS, "success" }, + { ICMP6_NI_REFUSED, "refused" }, + { ICMP6_NI_UNKNOWN, "unknown" }, + { -2, NULL } +}; + +static icmp_subtype_t icmprenumber6[] = { + { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" }, + { ICMP6_ROUTER_RENUMBERING_RESULT, "result" }, + { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" }, + { -2, NULL } +}; + +static icmp_type_t icmptypes6[] = { + { 0, NULL, 0, NULL }, + { ICMP6_DST_UNREACH, icmpredirect6, + IST_SZ(icmpredirect6), "unreach" }, + { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" }, + { ICMP6_TIME_EXCEEDED, icmptimexceed6, + IST_SZ(icmptimexceed6), "timxceed" }, + { ICMP6_PARAM_PROB, icmpparamprob6, + IST_SZ(icmpparamprob6), "paramprob" }, + { ICMP6_ECHO_REQUEST, NULL, 0, "echo" }, + { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" }, + { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6, + IST_SZ(icmpquerysubject6), "groupmemberquery" }, + { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" }, + { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" }, + { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" }, + { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" }, + { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" }, + { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" }, + { ND_REDIRECT, NULL, 0, "redirect" }, + { ICMP6_ROUTER_RENUMBERING, icmprenumber6, + IST_SZ(icmprenumber6), "routerrenumber" }, + { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" }, + { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" }, + { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" }, + { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" }, + { ICMP6_NI_QUERY, icmpnodeinfo6, + IST_SZ(icmpnodeinfo6), "nodeinforequest" }, + { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" }, + { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" }, + { MLD6_MTRACE, NULL, 0, "mtracerequest" }, + { -2, NULL, 0, NULL } +}; + +static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) +int type; +icmp_subtype_t *table; +size_t tablesz; +{ + icmp_subtype_t *ist; + int i; + + if (tablesz < 2) + return NULL; + + if ((type < 0) || (type > table[tablesz - 2].ist_val)) + return NULL; + + i = type; + if (table[type].ist_val == type) + return table + type; + + for (i = 0, ist = table; ist->ist_val != -2; i++, ist++) + if (ist->ist_val == type) + return ist; + return NULL; +} + + +static icmp_type_t *find_icmptype(type, table, tablesz) +int type; +icmp_type_t *table; +size_t tablesz; +{ + icmp_type_t *it; + int i; + + if (tablesz < 2) + return NULL; + + if ((type < 0) || (type > table[tablesz - 2].it_val)) + return NULL; + + i = type; + if (table[type].it_val == type) + return table + type; + + for (i = 0, it = table; it->it_val != -2; i++, it++) + if (it->it_val == type) + return it; + return NULL; +} + + +static void handlehup(sig) +int sig; +{ + signal(SIGHUP, handlehup); + donehup = 1; +} + + +static void init_tabs() +{ + struct protoent *p; + struct servent *s; + char *name, **tab; + int port, i; + + if (protocols != NULL) { + for (i = 0; i < 256; i++) + if (protocols[i] != NULL) { + free(protocols[i]); + protocols[i] = NULL; + } + free(protocols); + protocols = NULL; + } + protocols = (char **)malloc(256 * sizeof(*protocols)); + if (protocols != NULL) { + bzero((char *)protocols, 256 * sizeof(*protocols)); + + setprotoent(1); + while ((p = getprotoent()) != NULL) + if (p->p_proto >= 0 && p->p_proto <= 255 && + p->p_name != NULL && protocols[p->p_proto] == NULL) + protocols[p->p_proto] = strdup(p->p_name); + endprotoent(); + } + + if (udp_ports != NULL) { + for (i = 0; i < 65536; i++) + if (udp_ports[i] != NULL) { + free(udp_ports[i]); + udp_ports[i] = NULL; + } + free(udp_ports); + udp_ports = NULL; + } + udp_ports = (char **)malloc(65536 * sizeof(*udp_ports)); + if (udp_ports != NULL) + bzero((char *)udp_ports, 65536 * sizeof(*udp_ports)); + + if (tcp_ports != NULL) { + for (i = 0; i < 65536; i++) + if (tcp_ports[i] != NULL) { + free(tcp_ports[i]); + tcp_ports[i] = NULL; + } + free(tcp_ports); + tcp_ports = NULL; + } + tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports)); + if (tcp_ports != NULL) + bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports)); + + setservent(1); + while ((s = getservent()) != NULL) { + if (s->s_proto == NULL) + continue; + else if (!strcmp(s->s_proto, "tcp")) { + port = ntohs(s->s_port); + name = s->s_name; + tab = tcp_ports; + } else if (!strcmp(s->s_proto, "udp")) { + port = ntohs(s->s_port); + name = s->s_name; + tab = udp_ports; + } else + continue; + if ((port < 0 || port > 65535) || (name == NULL)) + continue; + if (tab != NULL) + tab[port] = strdup(name); + } + endservent(); +} + + +static char *getproto(p) +u_int p; +{ + static char pnum[4]; + char *s; + + p &= 0xff; + s = protocols ? protocols[p] : NULL; + if (s == NULL) { + sprintf(pnum, "%u", p); + s = pnum; + } + return s; +} + + +static int read_log(fd, lenp, buf, bufsize) +int fd, bufsize, *lenp; +char *buf; +{ + int nr; + + nr = read(fd, buf, bufsize); + if (!nr) + return 2; + if ((nr < 0) && (errno != EINTR)) + return -1; + *lenp = nr; + return 0; +} + + +char *hostname(res, v, ip) +int res, v; +u_32_t *ip; +{ +# define MAX_INETA 16 + static char hname[MAXHOSTNAMELEN + MAX_INETA + 3]; +#ifdef USE_INET6 + static char hostbuf[MAXHOSTNAMELEN+1]; +#endif + struct hostent *hp; + struct in_addr ipa; + + if (v == 4) { + ipa.s_addr = *ip; + if (!res) + return inet_ntoa(ipa); + hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET); + if (!hp) + return inet_ntoa(ipa); + sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, + inet_ntoa(ipa)); + return hname; + } +#ifdef USE_INET6 + (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); + hostbuf[MAXHOSTNAMELEN] = '\0'; + return hostbuf; +#else + return "IPv6"; +#endif +} + + +char *portname(res, proto, port) +int res; +char *proto; +u_int port; +{ + static char pname[8]; + char *s; + + port = ntohs(port); + port &= 0xffff; + (void) sprintf(pname, "%u", port); + if (!res || (opts & OPT_PORTNUM)) + return pname; + s = NULL; + if (!strcmp(proto, "tcp")) + s = tcp_ports[port]; + else if (!strcmp(proto, "udp")) + s = udp_ports[port]; + if (s == NULL) + s = pname; + return s; +} + + +static char *icmpname(type, code) +u_int type; +u_int code; +{ + static char name[80]; + icmp_subtype_t *ist; + icmp_type_t *it; + char *s; + + s = NULL; + it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it)); + if (it != NULL) + s = it->it_name; + + if (s == NULL) + sprintf(name, "icmptype(%d)/", type); + else + sprintf(name, "%s/", s); + + ist = NULL; + if (it != NULL && it->it_subtable != NULL) + ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); + + if (ist != NULL && ist->ist_name != NULL) + strcat(name, ist->ist_name); + else + sprintf(name + strlen(name), "%d", code); + + return name; +} + +static char *icmpname6(type, code) +u_int type; +u_int code; +{ + static char name[80]; + icmp_subtype_t *ist; + icmp_type_t *it; + char *s; + + s = NULL; + it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it)); + if (it != NULL) + s = it->it_name; + + if (s == NULL) + sprintf(name, "icmpv6type(%d)/", type); + else + sprintf(name, "%s/", s); + + ist = NULL; + if (it != NULL && it->it_subtable != NULL) + ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); + + if (ist != NULL && ist->ist_name != NULL) + strcat(name, ist->ist_name); + else + sprintf(name + strlen(name), "%d", code); + + return name; +} + + +void dumphex(log, dopts, buf, len) +FILE *log; +int dopts; +char *buf; +int len; +{ + char hline[80]; + int i, j, k; + u_char *s = (u_char *)buf, *t = (u_char *)hline; + + if (buf == NULL || len == 0) + return; + + *hline = '\0'; + + for (i = len, j = 0; i; i--, j++, s++) { + if (j && !(j & 0xf)) { + *t++ = '\n'; + *t = '\0'; + if (!(dopts & OPT_SYSLOG)) + fputs(hline, log); + else + syslog(LOG_INFO, "%s", hline); + t = (u_char *)hline; + *t = '\0'; + } + sprintf((char *)t, "%02x", *s & 0xff); + t += 2; + if (!((j + 1) & 0xf)) { + s -= 15; + sprintf((char *)t, " "); + t += 8; + for (k = 16; k; k--, s++) + *t++ = (ISPRINT(*s) ? *s : '.'); + s--; + } + + if ((j + 1) & 0xf) + *t++ = ' ';; + } + + if (j & 0xf) { + for (k = 16 - (j & 0xf); k; k--) { + *t++ = ' '; + *t++ = ' '; + *t++ = ' '; + } + sprintf((char *)t, " "); + t += 7; + s -= j & 0xf; + for (k = j & 0xf; k; k--, s++) + *t++ = (ISPRINT(*s) ? *s : '.'); + *t++ = '\n'; + *t = '\0'; + } + if (!(dopts & OPT_SYSLOG)) { + fputs(hline, log); + fflush(log); + } else + syslog(LOG_INFO, "%s", hline); +} + + +static struct tm *get_tm(sec) +#ifdef __hpux +u_32_t sec; +#else +time_t sec; +#endif +{ + struct tm *tm; + time_t t; + + t = sec; + tm = localtime(&t); + return tm; +} + +static void print_natlog(log, buf, blen) +FILE *log; +char *buf; +int blen; +{ + struct natlog *nl; + iplog_t *ipl = (iplog_t *)buf; + char *t = line; + struct tm *tm; + int res, i, len; + char *proto; + + nl = (struct natlog *)((char *)ipl + sizeof(*ipl)); + res = (opts & OPT_RESOLVE) ? 1 : 0; + tm = get_tm(ipl->ipl_sec); + len = sizeof(line); + if (!(opts & OPT_SYSLOG)) { + (void) strftime(t, len, "%d/%m/%Y ", tm); + i = strlen(t); + len -= i; + t += i; + } + (void) strftime(t, len, "%T", tm); + t += strlen(t); + (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1); + t += strlen(t); + + if (nl->nl_type == NL_NEWMAP) + strcpy(t, "NAT:MAP "); + else if (nl->nl_type == NL_NEWRDR) + strcpy(t, "NAT:RDR "); + else if (nl->nl_type == NL_FLUSH) + strcpy(t, "NAT:FLUSH "); + else if (nl->nl_type == NL_EXPIRE) + strcpy(t, "NAT:EXPIRE "); + else if (nl->nl_type == NL_NEWBIMAP) + strcpy(t, "NAT:BIMAP "); + else if (nl->nl_type == NL_NEWBLOCK) + strcpy(t, "NAT:MAPBLOCK "); + else if (nl->nl_type == NL_CLONE) + strcpy(t, "NAT:CLONE "); + else + sprintf(t, "Type: %d ", nl->nl_type); + t += strlen(t); + + proto = getproto(nl->nl_p); + + (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip), + portname(res, proto, (u_int)nl->nl_inport)); + t += strlen(t); + (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip), + portname(res, proto, (u_int)nl->nl_outport)); + t += strlen(t); + (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip), + portname(res, proto, (u_int)nl->nl_origport)); + t += strlen(t); + if (nl->nl_type == NL_EXPIRE) { +#ifdef USE_QUAD_T + (void) sprintf(t, " Pkts %qd/%qd Bytes %qd/%qd", + (long long)nl->nl_pkts[0], + (long long)nl->nl_pkts[1], + (long long)nl->nl_bytes[0], + (long long)nl->nl_bytes[1]); +#else + (void) sprintf(t, " Pkts %ld/%ld Bytes %ld/%ld", + nl->nl_pkts[0], nl->nl_pkts[1], + nl->nl_bytes[0], nl->nl_bytes[1]); +#endif + t += strlen(t); + } + + *t++ = '\n'; + *t++ = '\0'; + if (opts & OPT_SYSLOG) + syslog(LOG_INFO, "%s", line); + else + (void) fprintf(log, "%s", line); +} + + +static void print_statelog(log, buf, blen) +FILE *log; +char *buf; +int blen; +{ + struct ipslog *sl; + iplog_t *ipl = (iplog_t *)buf; + char *t = line, *proto; + struct tm *tm; + int res, i, len; + + sl = (struct ipslog *)((char *)ipl + sizeof(*ipl)); + res = (opts & OPT_RESOLVE) ? 1 : 0; + tm = get_tm(ipl->ipl_sec); + len = sizeof(line); + if (!(opts & OPT_SYSLOG)) { + (void) strftime(t, len, "%d/%m/%Y ", tm); + i = strlen(t); + len -= i; + t += i; + } + (void) strftime(t, len, "%T", tm); + t += strlen(t); + (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); + t += strlen(t); + + if (sl->isl_type == ISL_NEW) + strcpy(t, "STATE:NEW "); + else if (sl->isl_type == ISL_CLONE) + strcpy(t, "STATE:CLONED "); + else if (sl->isl_type == ISL_EXPIRE) { + if ((sl->isl_p == IPPROTO_TCP) && + (sl->isl_state[0] > IPF_TCPS_ESTABLISHED || + sl->isl_state[1] > IPF_TCPS_ESTABLISHED)) + strcpy(t, "STATE:CLOSE "); + else + strcpy(t, "STATE:EXPIRE "); + } else if (sl->isl_type == ISL_FLUSH) + strcpy(t, "STATE:FLUSH "); + else if (sl->isl_type == ISL_INTERMEDIATE) + strcpy(t, "STATE:INTERMEDIATE "); + else if (sl->isl_type == ISL_REMOVE) + strcpy(t, "STATE:REMOVE "); + else if (sl->isl_type == ISL_KILLED) + strcpy(t, "STATE:KILLED "); + else + sprintf(t, "Type: %d ", sl->isl_type); + t += strlen(t); + + proto = getproto(sl->isl_p); + + if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { + (void) sprintf(t, "%s,%s -> ", + hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src), + portname(res, proto, (u_int)sl->isl_sport)); + t += strlen(t); + (void) sprintf(t, "%s,%s PR %s", + hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), + portname(res, proto, (u_int)sl->isl_dport), proto); + } else if (sl->isl_p == IPPROTO_ICMP) { + (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, + (u_32_t *)&sl->isl_src)); + t += strlen(t); + (void) sprintf(t, "%s PR icmp %d", + hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), + sl->isl_itype); + } else if (sl->isl_p == IPPROTO_ICMPV6) { + (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, + (u_32_t *)&sl->isl_src)); + t += strlen(t); + (void) sprintf(t, "%s PR icmpv6 %d", + hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), + sl->isl_itype); + } else { + (void) sprintf(t, "%s -> ", + hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src)); + t += strlen(t); + (void) sprintf(t, "%s PR %s", + hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), + proto); + } + t += strlen(t); + if (sl->isl_tag != FR_NOLOGTAG) { + (void) sprintf(t, " tag %u", sl->isl_tag); + t += strlen(t); + } + if (sl->isl_type != ISL_NEW) { + sprintf(t, +#ifdef USE_QUAD_T +#ifdef PRId64 + " Forward: Pkts in %" PRId64 " Bytes in %" PRId64 + " Pkts out %" PRId64 " Bytes out %" PRId64 + " Backward: Pkts in %" PRId64 " Bytes in %" PRId64 + " Pkts out %" PRId64 " Bytes out %" PRId64, +#else + " Forward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd Backward: Pkts in %qd Bytes in %qd Pkts out %qd Bytes out %qd", +#endif /* PRId64 */ +#else + " Forward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld Backward: Pkts in %ld Bytes in %ld Pkts out %ld Bytes out %ld", +#endif + sl->isl_pkts[0], sl->isl_bytes[0], + sl->isl_pkts[1], sl->isl_bytes[1], + sl->isl_pkts[2], sl->isl_bytes[2], + sl->isl_pkts[3], sl->isl_bytes[3]); + + t += strlen(t); + } + + *t++ = '\n'; + *t++ = '\0'; + if (opts & OPT_SYSLOG) + syslog(LOG_INFO, "%s", line); + else + (void) fprintf(log, "%s", line); +} + + +static void print_log(logtype, log, buf, blen) +FILE *log; +char *buf; +int logtype, blen; +{ + iplog_t *ipl; + char *bp = NULL, *bpo = NULL; + int psize; + + while (blen > 0) { + ipl = (iplog_t *)buf; + if ((u_long)ipl & (sizeof(long)-1)) { + if (bp) + bpo = bp; + bp = (char *)malloc(blen); + bcopy((char *)ipl, bp, blen); + if (bpo) { + free(bpo); + bpo = NULL; + } + buf = bp; + continue; + } + + psize = ipl->ipl_dsize; + if (psize > blen) + break; + + if (binarylog) { + fwrite(buf, psize, 1, binarylog); + fflush(binarylog); + } + + if (logtype == IPL_LOGIPF) { + if (ipl->ipl_magic == IPL_MAGIC) + print_ipflog(log, buf, psize); + + } else if (logtype == IPL_LOGNAT) { + if (ipl->ipl_magic == IPL_MAGIC_NAT) + print_natlog(log, buf, psize); + + } else if (logtype == IPL_LOGSTATE) { + if (ipl->ipl_magic == IPL_MAGIC_STATE) + print_statelog(log, buf, psize); + } + + blen -= psize; + buf += psize; + } + if (bp) + free(bp); + return; +} + + +static void print_ipflog(log, buf, blen) +FILE *log; +char *buf; +int blen; +{ + tcphdr_t *tp; + struct icmp *ic; + struct icmp *icmp; + struct tm *tm; + char *t, *proto; + int i, v, lvl, res, len, off, plen, ipoff, defaction; + ip_t *ipc, *ip; + u_32_t *s, *d; + u_short hl, p; + ipflog_t *ipf; + iplog_t *ipl; +#ifdef USE_INET6 + ip6_t *ip6; +#endif + + ipl = (iplog_t *)buf; + ipf = (ipflog_t *)((char *)buf + sizeof(*ipl)); + ip = (ip_t *)((char *)ipf + sizeof(*ipf)); + v = IP_V(ip); + res = (opts & OPT_RESOLVE) ? 1 : 0; + t = line; + *t = '\0'; + tm = get_tm(ipl->ipl_sec); + + len = sizeof(line); + if (!(opts & OPT_SYSLOG)) { + (void) strftime(t, len, "%d/%m/%Y ", tm); + i = strlen(t); + len -= i; + t += i; + } + (void) strftime(t, len, "%T", tm); + t += strlen(t); + (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); + t += strlen(t); + if (ipl->ipl_count > 1) { + (void) sprintf(t, "%dx ", ipl->ipl_count); + t += strlen(t); + } +#if (defined(MENTAT) || \ + (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ + (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \ + (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux) + { + char ifname[sizeof(ipf->fl_ifname) + 1]; + + strncpy(ifname, ipf->fl_ifname, sizeof(ipf->fl_ifname)); + ifname[sizeof(ipf->fl_ifname)] = '\0'; + (void) sprintf(t, "%s", ifname); + t += strlen(t); +# if defined(MENTAT) || defined(linux) + if (ISALPHA(*(t - 1))) { + sprintf(t, "%d", ipf->fl_unit); + t += strlen(t); + } +# endif + } +#else + for (len = 0; len < 3; len++) + if (ipf->fl_ifname[len] == '\0') + break; + if (ipf->fl_ifname[len]) + len++; + (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); + t += strlen(t); +#endif +#ifdef __sgi + if ((ipf->fl_group[0] == 255) && (ipf->fl_group[1] == '\0')) +#else + if ((ipf->fl_group[0] == -1) && (ipf->fl_group[1] == '\0')) +#endif + strcat(t, " @-1:"); + else if (ipf->fl_group[0] == '\0') + (void) strcpy(t, " @0:"); + else + (void) sprintf(t, " @%s:", ipf->fl_group); + t += strlen(t); + if (ipf->fl_rule == 0xffffffff) + strcat(t, "-1 "); + else + (void) sprintf(t, "%u ", ipf->fl_rule + 1); + t += strlen(t); + + lvl = LOG_NOTICE; + + if (ipf->fl_lflags & FI_SHORT) { + *t++ = 'S'; + lvl = LOG_ERR; + } + + if (FR_ISPASS(ipf->fl_flags)) { + if (ipf->fl_flags & FR_LOGP) + *t++ = 'p'; + else + *t++ = 'P'; + } else if (FR_ISBLOCK(ipf->fl_flags)) { + if (ipf->fl_flags & FR_LOGB) + *t++ = 'b'; + else + *t++ = 'B'; + lvl = LOG_WARNING; + } else if ((ipf->fl_flags & FR_LOGMASK) == FR_LOG) { + *t++ = 'L'; + lvl = LOG_INFO; + } else if (ipf->fl_flags & FF_LOGNOMATCH) { + *t++ = 'n'; + } else { + *t++ = '?'; + lvl = LOG_EMERG; + } + if (ipf->fl_loglevel != 0xffff) + lvl = ipf->fl_loglevel; + *t++ = ' '; + *t = '\0'; + + if (v == 6) { +#ifdef USE_INET6 + off = 0; + ipoff = 0; + hl = sizeof(ip6_t); + ip6 = (ip6_t *)ip; + p = (u_short)ip6->ip6_nxt; + s = (u_32_t *)&ip6->ip6_src; + d = (u_32_t *)&ip6->ip6_dst; + plen = hl + ntohs(ip6->ip6_plen); +#else + sprintf(t, "ipv6"); + goto printipflog; +#endif + } else if (v == 4) { + hl = IP_HL(ip) << 2; + ipoff = ip->ip_off; + off = ipoff & IP_OFFMASK; + p = (u_short)ip->ip_p; + s = (u_32_t *)&ip->ip_src; + d = (u_32_t *)&ip->ip_dst; + plen = ip->ip_len; + } else { + goto printipflog; + } + proto = getproto(p); + + if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { + tp = (tcphdr_t *)((char *)ip + hl); + if (!(ipf->fl_lflags & FI_SHORT)) { + (void) sprintf(t, "%s,%s -> ", hostname(res, v, s), + portname(res, proto, (u_int)tp->th_sport)); + t += strlen(t); + (void) sprintf(t, "%s,%s PR %s len %hu %hu", + hostname(res, v, d), + portname(res, proto, (u_int)tp->th_dport), + proto, hl, plen); + t += strlen(t); + + if (p == IPPROTO_TCP) { + *t++ = ' '; + *t++ = '-'; + for (i = 0; tcpfl[i].value; i++) + if (tp->th_flags & tcpfl[i].value) + *t++ = tcpfl[i].flag; + if (opts & OPT_VERBOSE) { + (void) sprintf(t, " %lu %lu %hu", + (u_long)(ntohl(tp->th_seq)), + (u_long)(ntohl(tp->th_ack)), + ntohs(tp->th_win)); + t += strlen(t); + } + } + *t = '\0'; + } else { + (void) sprintf(t, "%s -> ", hostname(res, v, s)); + t += strlen(t); + (void) sprintf(t, "%s PR %s len %hu %hu", + hostname(res, v, d), proto, hl, plen); + } + } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) { + ic = (struct icmp *)((char *)ip + hl); + (void) sprintf(t, "%s -> ", hostname(res, v, s)); + t += strlen(t); + (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", + hostname(res, v, d), hl, plen, + icmpname6(ic->icmp_type, ic->icmp_code)); + } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) { + ic = (struct icmp *)((char *)ip + hl); + (void) sprintf(t, "%s -> ", hostname(res, v, s)); + t += strlen(t); + (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s", + hostname(res, v, d), hl, plen, + icmpname(ic->icmp_type, ic->icmp_code)); + if (ic->icmp_type == ICMP_UNREACH || + ic->icmp_type == ICMP_SOURCEQUENCH || + ic->icmp_type == ICMP_PARAMPROB || + ic->icmp_type == ICMP_REDIRECT || + ic->icmp_type == ICMP_TIMXCEED) { + ipc = &ic->icmp_ip; + i = ntohs(ipc->ip_len); + /* + * XXX - try to guess endian of ip_len in ICMP + * returned data. + */ + if (i > 1500) + i = ipc->ip_len; + ipoff = ntohs(ipc->ip_off); + proto = getproto(ipc->ip_p); + + if (!(ipoff & IP_OFFMASK) && + ((ipc->ip_p == IPPROTO_TCP) || + (ipc->ip_p == IPPROTO_UDP))) { + tp = (tcphdr_t *)((char *)ipc + hl); + t += strlen(t); + (void) sprintf(t, " for %s,%s -", + HOSTNAME_V4(res, ipc->ip_src), + portname(res, proto, + (u_int)tp->th_sport)); + t += strlen(t); + (void) sprintf(t, " %s,%s PR %s len %hu %hu", + HOSTNAME_V4(res, ipc->ip_dst), + portname(res, proto, + (u_int)tp->th_dport), + proto, IP_HL(ipc) << 2, i); + } else if (!(ipoff & IP_OFFMASK) && + (ipc->ip_p == IPPROTO_ICMP)) { + icmp = (icmphdr_t *)((char *)ipc + hl); + + t += strlen(t); + (void) sprintf(t, " for %s -", + HOSTNAME_V4(res, ipc->ip_src)); + t += strlen(t); + (void) sprintf(t, + " %s PR icmp len %hu %hu icmp %d/%d", + HOSTNAME_V4(res, ipc->ip_dst), + IP_HL(ipc) << 2, i, + icmp->icmp_type, icmp->icmp_code); + } else { + t += strlen(t); + (void) sprintf(t, " for %s -", + HOSTNAME_V4(res, ipc->ip_src)); + t += strlen(t); + (void) sprintf(t, " %s PR %s len %hu (%hu)", + HOSTNAME_V4(res, ipc->ip_dst), proto, + IP_HL(ipc) << 2, i); + t += strlen(t); + if (ipoff & IP_OFFMASK) { + (void) sprintf(t, + "(frag %d:%hu@%hu%s%s)", + ntohs(ipc->ip_id), + i - (IP_HL(ipc) << 2), + (ipoff & IP_OFFMASK) << 3, + ipoff & IP_MF ? "+" : "", + ipoff & IP_DF ? "-" : ""); + } + } + + } + } else { + (void) sprintf(t, "%s -> ", hostname(res, v, s)); + t += strlen(t); + (void) sprintf(t, "%s PR %s len %hu (%hu)", + hostname(res, v, d), proto, hl, plen); + t += strlen(t); + if (off & IP_OFFMASK) + (void) sprintf(t, " (frag %d:%hu@%hu%s%s)", + ntohs(ip->ip_id), + plen - hl, (off & IP_OFFMASK) << 3, + ipoff & IP_MF ? "+" : "", + ipoff & IP_DF ? "-" : ""); + } + t += strlen(t); + +printipflog: + if (ipf->fl_flags & FR_KEEPSTATE) { + (void) strcpy(t, " K-S"); + t += strlen(t); + } + + if (ipf->fl_flags & FR_KEEPFRAG) { + (void) strcpy(t, " K-F"); + t += strlen(t); + } + + if (ipf->fl_dir == 0) + strcpy(t, " IN"); + else if (ipf->fl_dir == 1) + strcpy(t, " OUT"); + t += strlen(t); + if (ipf->fl_logtag != 0) { + sprintf(t, " log-tag %d", ipf->fl_logtag); + t += strlen(t); + } + if (ipf->fl_nattag.ipt_num[0] != 0) { + strcpy(t, " nat-tag "); + t += strlen(t); + strncpy(t, ipf->fl_nattag.ipt_tag, sizeof(ipf->fl_nattag)); + t += strlen(t); + } + if ((ipf->fl_lflags & FI_LOWTTL) != 0) { + strcpy(t, " low-ttl"); + t += 8; + } + if ((ipf->fl_lflags & FI_OOW) != 0) { + strcpy(t, " OOW"); + t += 4; + } + if ((ipf->fl_lflags & FI_BAD) != 0) { + strcpy(t, " bad"); + t += 4; + } + if ((ipf->fl_lflags & FI_NATED) != 0) { + strcpy(t, " NAT"); + t += 4; + } + if ((ipf->fl_lflags & FI_BADNAT) != 0) { + strcpy(t, " bad-NAT"); + t += 8; + } + if ((ipf->fl_lflags & FI_BADSRC) != 0) { + strcpy(t, " bad-src"); + t += 8; + } + if ((ipf->fl_lflags & FI_MULTICAST) != 0) { + strcpy(t, " multicast"); + t += 10; + } + if ((ipf->fl_lflags & FI_BROADCAST) != 0) { + strcpy(t, " broadcast"); + t += 10; + } + if ((ipf->fl_lflags & (FI_MULTICAST|FI_BROADCAST|FI_MBCAST)) == + FI_MBCAST) { + strcpy(t, " mbcast"); + t += 7; + } + *t++ = '\n'; + *t++ = '\0'; + defaction = 0; + if (conf_file != NULL) + defaction = check_action(buf, line, opts, lvl); + if (defaction == 0) { + if (opts & OPT_SYSLOG) + syslog(lvl, "%s", line); + else + (void) fprintf(log, "%s", line); + if (opts & OPT_HEXHDR) + dumphex(log, opts, buf, + sizeof(iplog_t) + sizeof(*ipf)); + if (opts & OPT_HEXBODY) + dumphex(log, opts, (char *)ip, + ipf->fl_plen + ipf->fl_hlen); + else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) + dumphex(log, opts, (char *)ip + ipf->fl_hlen, + ipf->fl_plen); + } +} + + +static void usage(prog) +char *prog; +{ + fprintf(stderr, "%s: [-NFhstvxX] [-f ]\n", prog); + exit(1); +} + + +static void write_pid(file) +char *file; +{ + FILE *fp = NULL; + int fd; + + if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0) { + fp = fdopen(fd, "w"); + if (fp == NULL) { + close(fd); + fprintf(stderr, + "unable to open/create pid file: %s\n", file); + return; + } + fprintf(fp, "%d", getpid()); + fclose(fp); + } +} + + +static void flushlogs(file, log) +char *file; +FILE *log; +{ + int fd, flushed = 0; + + if ((fd = open(file, O_RDWR)) == -1) { + (void) fprintf(stderr, "%s: open: %s\n", + file, STRERROR(errno)); + exit(1); + } + + if (ioctl(fd, SIOCIPFFB, &flushed) == 0) { + printf("%d bytes flushed from log buffer\n", + flushed); + fflush(stdout); + } else + perror("SIOCIPFFB"); + (void) close(fd); + + if (flushed) { + if (opts & OPT_SYSLOG) + syslog(LOG_INFO, "%d bytes flushed from log\n", + flushed); + else if (log != stdout) + fprintf(log, "%d bytes flushed from log\n", flushed); + } +} + + +static void logopts(turnon, options) +int turnon; +char *options; +{ + int flags = 0; + char *s; + + for (s = options; *s; s++) + { + switch (*s) + { + case 'N' : + flags |= OPT_NAT; + break; + case 'S' : + flags |= OPT_STATE; + break; + case 'I' : + flags |= OPT_FILTER; + break; + default : + fprintf(stderr, "Unknown log option %c\n", *s); + exit(1); + } + } + + if (turnon) + opts |= flags; + else + opts &= ~(flags); +} + + +int main(argc, argv) +int argc; +char *argv[]; +{ + struct stat sb; + FILE *log = stdout; + FILE *fp; + int fd[3], doread, n, i; + int tr, nr, regular[3], c; + int fdt[3], devices = 0, make_daemon = 0; + char buf[DEFAULT_IPFLOGSIZE], *iplfile[3], *s; + extern int optind; + extern char *optarg; + + fd[0] = fd[1] = fd[2] = -1; + fdt[0] = fdt[1] = fdt[2] = -1; + iplfile[0] = IPL_NAME; + iplfile[1] = IPNAT_NAME; + iplfile[2] = IPSTATE_NAME; + + while ((c = getopt(argc, argv, "?abB:C:Df:FhnN:o:O:pP:sS:tvxX")) != -1) + switch (c) + { + case 'a' : + opts |= OPT_LOGALL; + fdt[0] = IPL_LOGIPF; + fdt[1] = IPL_LOGNAT; + fdt[2] = IPL_LOGSTATE; + break; + case 'b' : + opts |= OPT_LOGBODY; + break; + case 'B' : + binarylogfile = optarg; + binarylog = fopen(optarg, "a"); + break; + case 'C' : + conf_file = optarg; + break; + case 'D' : + make_daemon = 1; + break; + case 'f' : case 'I' : + opts |= OPT_FILTER; + fdt[0] = IPL_LOGIPF; + iplfile[0] = optarg; + break; + case 'F' : + flushlogs(iplfile[0], log); + flushlogs(iplfile[1], log); + flushlogs(iplfile[2], log); + break; + case 'n' : + opts |= OPT_RESOLVE; + break; + case 'N' : + opts |= OPT_NAT; + fdt[1] = IPL_LOGNAT; + iplfile[1] = optarg; + break; + case 'o' : case 'O' : + logopts(c == 'o', optarg); + fdt[0] = fdt[1] = fdt[2] = -1; + if (opts & OPT_FILTER) + fdt[0] = IPL_LOGIPF; + if (opts & OPT_NAT) + fdt[1] = IPL_LOGNAT; + if (opts & OPT_STATE) + fdt[2] = IPL_LOGSTATE; + break; + case 'p' : + opts |= OPT_PORTNUM; + break; + case 'P' : + pidfile = optarg; + break; + case 's' : + s = strrchr(argv[0], '/'); + if (s == NULL) + s = argv[0]; + else + s++; + openlog(s, LOG_NDELAY|LOG_PID, LOGFAC); + s = NULL; + opts |= OPT_SYSLOG; + log = NULL; + break; + case 'S' : + opts |= OPT_STATE; + fdt[2] = IPL_LOGSTATE; + iplfile[2] = optarg; + break; + case 't' : + opts |= OPT_TAIL; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + case 'x' : + opts |= OPT_HEXBODY; + break; + case 'X' : + opts |= OPT_HEXHDR; + break; + default : + case 'h' : + case '?' : + usage(argv[0]); + } + + init_tabs(); + if (conf_file) + if (load_config(conf_file) == -1) + exit(1); + + /* + * Default action is to only open the filter log file. + */ + if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1)) + fdt[0] = IPL_LOGIPF; + + for (i = 0; i < 3; i++) { + if (fdt[i] == -1) + continue; + if (!strcmp(iplfile[i], "-")) + fd[i] = 0; + else { + if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) { + (void) fprintf(stderr, + "%s: open: %s\n", iplfile[i], + STRERROR(errno)); + exit(1); + /* NOTREACHED */ + } + if (fstat(fd[i], &sb) == -1) { + (void) fprintf(stderr, "%d: fstat: %s\n", + fd[i], STRERROR(errno)); + exit(1); + /* NOTREACHED */ + } + if (!(regular[i] = !S_ISCHR(sb.st_mode))) + devices++; + } + } + + if (!(opts & OPT_SYSLOG)) { + logfile = argv[optind]; + log = logfile ? fopen(logfile, "a") : stdout; + if (log == NULL) { + (void) fprintf(stderr, "%s: fopen: %s\n", + argv[optind], STRERROR(errno)); + exit(1); + /* NOTREACHED */ + } + setvbuf(log, NULL, _IONBF, 0); + } else + log = NULL; + + if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) { +#if BSD >= 199306 + daemon(0, !(opts & OPT_SYSLOG)); +#else + int pid; + if ((pid = fork()) > 0) + exit(0); + if (pid < 0) { + (void) fprintf(stderr, "%s: fork() failed: %s\n", + argv[0], STRERROR(errno)); + exit(1); + /* NOTREACHED */ + } + setsid(); + if ((opts & OPT_SYSLOG)) + close(2); +#endif /* !BSD */ + close(0); + close(1); + } + write_pid(pidfile); + + signal(SIGHUP, handlehup); + + for (doread = 1; doread; ) { + nr = 0; + + for (i = 0; i < 3; i++) { + tr = 0; + if (fdt[i] == -1) + continue; + if (!regular[i]) { + if (ioctl(fd[i], FIONREAD, &tr) == -1) { + if (opts & OPT_SYSLOG) + syslog(LOG_CRIT, + "ioctl(FIONREAD): %m"); + else + perror("ioctl(FIONREAD)"); + exit(1); + /* NOTREACHED */ + } + } else { + tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size); + if (!tr && !(opts & OPT_TAIL)) + doread = 0; + } + if (!tr) + continue; + nr += tr; + + tr = read_log(fd[i], &n, buf, sizeof(buf)); + if (donehup) { + if (logfile && (fp = fopen(logfile, "a"))) { + fclose(log); + log = fp; + } + if (binarylogfile && (fp = fopen(binarylogfile, "a"))) { + fclose(binarylog); + binarylog = fp; + } + init_tabs(); + if (conf_file != NULL) + load_config(conf_file); + donehup = 0; + } + + switch (tr) + { + case -1 : + if (opts & OPT_SYSLOG) + syslog(LOG_CRIT, "read: %m\n"); + else + perror("read"); + doread = 0; + break; + case 1 : + if (opts & OPT_SYSLOG) + syslog(LOG_CRIT, "aborting logging\n"); + else + fprintf(log, "aborting logging\n"); + doread = 0; + break; + case 2 : + break; + case 0 : + if (n > 0) { + print_log(fdt[i], log, buf, n); + if (!(opts & OPT_SYSLOG)) + fflush(log); + } + break; + } + } + if (!nr && ((opts & OPT_TAIL) || devices)) + sleep(1); + } + return(0); + /* NOTREACHED */ +} diff --git a/contrib/ipfilter/tools/ipmon_y.y b/contrib/ipfilter/tools/ipmon_y.y new file mode 100644 index 000000000000..8b300288c8d1 --- /dev/null +++ b/contrib/ipfilter/tools/ipmon_y.y @@ -0,0 +1,694 @@ +/* $NetBSD$ */ + +%{ +#include "ipf.h" +#include +#undef OPT_NAT +#undef OPT_VERBOSE +#include "ipmon_l.h" +#include "ipmon.h" + +#define YYDEBUG 1 + +extern void yyerror __P((char *)); +extern int yyparse __P((void)); +extern int yylex __P((void)); +extern int yydebug; +extern FILE *yyin; +extern int yylineNum; + +typedef struct opt { + struct opt *o_next; + int o_line; + int o_type; + int o_num; + char *o_str; + struct in_addr o_ip; +} opt_t; + +static void build_action __P((struct opt *)); +static opt_t *new_opt __P((int)); +static void free_action __P((ipmon_action_t *)); + +static ipmon_action_t *alist = NULL; +%} + +%union { + char *str; + u_32_t num; + struct in_addr addr; + struct opt *opt; + union i6addr ip6; +} + +%token YY_NUMBER YY_HEX +%token YY_STR +%token YY_IPV6 +%token YY_COMMENT +%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT +%token YY_RANGE_OUT YY_RANGE_IN + +%token IPM_MATCH IPM_BODY IPM_COMMENT IPM_DIRECTION IPM_DSTIP IPM_DSTPORT +%token IPM_EVERY IPM_EXECUTE IPM_GROUP IPM_INTERFACE IPM_IN IPM_NO IPM_OUT +%token IPM_PACKET IPM_PACKETS IPM_POOL IPM_PROTOCOL IPM_RESULT IPM_RULE +%token IPM_SECOND IPM_SECONDS IPM_SRCIP IPM_SRCPORT IPM_LOGTAG IPM_WITH +%token IPM_DO IPM_SAVE IPM_SYSLOG IPM_NOTHING IPM_RAW IPM_TYPE IPM_NAT +%token IPM_STATE IPM_NATTAG IPM_IPF +%type ipv4 +%type direction dstip dstport every execute group interface +%type protocol result rule srcip srcport logtag matching +%type matchopt nattag type doopt doing save syslog nothing +%type saveopts saveopt typeopt + +%% +file: line + | assign + | file line + | file assign + ; + +line: IPM_MATCH '{' matching '}' IPM_DO '{' doing '}' ';' + { build_action($3); resetlexer(); } + | IPM_COMMENT + | YY_COMMENT + ; + +assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); + resetlexer(); + free($1); + free($3); + } + ; + +assigning: + '=' { yyvarnext = 1; } + ; + +matching: + matchopt { $$ = $1; } + | matchopt ',' matching { $1->o_next = $3; $$ = $1; } + ; + +matchopt: + direction { $$ = $1; } + | dstip { $$ = $1; } + | dstport { $$ = $1; } + | every { $$ = $1; } + | group { $$ = $1; } + | interface { $$ = $1; } + | protocol { $$ = $1; } + | result { $$ = $1; } + | rule { $$ = $1; } + | srcip { $$ = $1; } + | srcport { $$ = $1; } + | logtag { $$ = $1; } + | nattag { $$ = $1; } + | type { $$ = $1; } + ; + +doing: + doopt { $$ = $1; } + | doopt ',' doing { $1->o_next = $3; $$ = $1; } + ; + +doopt: + execute { $$ = $1; } + | save { $$ = $1; } + | syslog { $$ = $1; } + | nothing { $$ = $1; } + ; + +direction: + IPM_DIRECTION '=' IPM_IN { $$ = new_opt(IPM_DIRECTION); + $$->o_num = IPM_IN; } + | IPM_DIRECTION '=' IPM_OUT { $$ = new_opt(IPM_DIRECTION); + $$->o_num = IPM_OUT; } + ; + +dstip: IPM_DSTIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_DSTIP); + $$->o_ip = $3; + $$->o_num = $5; } + ; + +dstport: + IPM_DSTPORT '=' YY_NUMBER { $$ = new_opt(IPM_DSTPORT); + $$->o_num = $3; } + | IPM_DSTPORT '=' YY_STR { $$ = new_opt(IPM_DSTPORT); + $$->o_str = $3; } + ; + +every: IPM_EVERY IPM_SECOND { $$ = new_opt(IPM_SECOND); + $$->o_num = 1; } + | IPM_EVERY YY_NUMBER IPM_SECONDS { $$ = new_opt(IPM_SECOND); + $$->o_num = $2; } + | IPM_EVERY IPM_PACKET { $$ = new_opt(IPM_PACKET); + $$->o_num = 1; } + | IPM_EVERY YY_NUMBER IPM_PACKETS { $$ = new_opt(IPM_PACKET); + $$->o_num = $2; } + ; + +group: IPM_GROUP '=' YY_NUMBER { $$ = new_opt(IPM_GROUP); + $$->o_num = $3; } + | IPM_GROUP '=' YY_STR { $$ = new_opt(IPM_GROUP); + $$->o_str = $3; } + ; + +interface: + IPM_INTERFACE '=' YY_STR { $$ = new_opt(IPM_INTERFACE); + $$->o_str = $3; } + ; + +logtag: IPM_LOGTAG '=' YY_NUMBER { $$ = new_opt(IPM_LOGTAG); + $$->o_num = $3; } + ; + +nattag: IPM_NATTAG '=' YY_STR { $$ = new_opt(IPM_NATTAG); + $$->o_str = $3; } + ; + +protocol: + IPM_PROTOCOL '=' YY_NUMBER { $$ = new_opt(IPM_PROTOCOL); + $$->o_num = $3; } + | IPM_PROTOCOL '=' YY_STR { $$ = new_opt(IPM_PROTOCOL); + $$->o_num = getproto($3); + free($3); + } + ; + +result: IPM_RESULT '=' YY_STR { $$ = new_opt(IPM_RESULT); + $$->o_str = $3; } + ; + +rule: IPM_RULE '=' YY_NUMBER { $$ = new_opt(IPM_RULE); + $$->o_num = YY_NUMBER; } + ; + +srcip: IPM_SRCIP '=' ipv4 '/' YY_NUMBER { $$ = new_opt(IPM_SRCIP); + $$->o_ip = $3; + $$->o_num = $5; } + ; + +srcport: + IPM_SRCPORT '=' YY_NUMBER { $$ = new_opt(IPM_SRCPORT); + $$->o_num = $3; } + | IPM_SRCPORT '=' YY_STR { $$ = new_opt(IPM_SRCPORT); + $$->o_str = $3; } + ; + +type: IPM_TYPE '=' typeopt { $$ = new_opt(IPM_TYPE); + $$->o_num = $3; } + ; + +typeopt: + IPM_IPF { $$ = IPL_MAGIC; } + | IPM_NAT { $$ = IPL_MAGIC_NAT; } + | IPM_STATE { $$ = IPL_MAGIC_STATE; } + ; + +execute: + IPM_EXECUTE YY_STR { $$ = new_opt(IPM_EXECUTE); + $$->o_str = $2; } + ; + +save: IPM_SAVE saveopts YY_STR { $$ = new_opt(IPM_SAVE); + $$->o_num = $2; + $$->o_str = $3; } + ; + +saveopts: { $$ = 0; } + | saveopt { $$ = $1; } + | saveopt ',' saveopts { $$ = $1 | $3; } + ; + +saveopt: + IPM_RAW { $$ = IPMDO_SAVERAW; } + ; + +syslog: IPM_SYSLOG { $$ = new_opt(IPM_SYSLOG); } + ; + +nothing: + IPM_NOTHING { $$ = 0; } + ; + +ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER + { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { + yyerror("Invalid octet string for IP address"); + return 0; + } + $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; + $$.s_addr = htonl($$.s_addr); + } +%% +static struct wordtab yywords[] = { + { "body", IPM_BODY }, + { "direction", IPM_DIRECTION }, + { "do", IPM_DO }, + { "dstip", IPM_DSTIP }, + { "dstport", IPM_DSTPORT }, + { "every", IPM_EVERY }, + { "execute", IPM_EXECUTE }, + { "group", IPM_GROUP }, + { "in", IPM_IN }, + { "interface", IPM_INTERFACE }, + { "ipf", IPM_IPF }, + { "logtag", IPM_LOGTAG }, + { "match", IPM_MATCH }, + { "nat", IPM_NAT }, + { "nattag", IPM_NATTAG }, + { "no", IPM_NO }, + { "nothing", IPM_NOTHING }, + { "out", IPM_OUT }, + { "packet", IPM_PACKET }, + { "packets", IPM_PACKETS }, + { "protocol", IPM_PROTOCOL }, + { "result", IPM_RESULT }, + { "rule", IPM_RULE }, + { "save", IPM_SAVE }, + { "second", IPM_SECOND }, + { "seconds", IPM_SECONDS }, + { "srcip", IPM_SRCIP }, + { "srcport", IPM_SRCPORT }, + { "state", IPM_STATE }, + { "syslog", IPM_SYSLOG }, + { "with", IPM_WITH }, + { NULL, 0 } +}; + +static int macflags[17][2] = { + { IPM_DIRECTION, IPMAC_DIRECTION }, + { IPM_DSTIP, IPMAC_DSTIP }, + { IPM_DSTPORT, IPMAC_DSTPORT }, + { IPM_GROUP, IPMAC_GROUP }, + { IPM_INTERFACE, IPMAC_INTERFACE }, + { IPM_LOGTAG, IPMAC_LOGTAG }, + { IPM_NATTAG, IPMAC_NATTAG }, + { IPM_PACKET, IPMAC_EVERY }, + { IPM_PROTOCOL, IPMAC_PROTOCOL }, + { IPM_RESULT, IPMAC_RESULT }, + { IPM_RULE, IPMAC_RULE }, + { IPM_SECOND, IPMAC_EVERY }, + { IPM_SRCIP, IPMAC_SRCIP }, + { IPM_SRCPORT, IPMAC_SRCPORT }, + { IPM_TYPE, IPMAC_TYPE }, + { IPM_WITH, IPMAC_WITH }, + { 0, 0 } +}; + +static opt_t *new_opt(type) +int type; +{ + opt_t *o; + + o = (opt_t *)malloc(sizeof(*o)); + o->o_type = type; + o->o_line = yylineNum; + o->o_num = 0; + o->o_str = (char *)0; + o->o_next = NULL; + return o; +} + +static void build_action(olist) +opt_t *olist; +{ + ipmon_action_t *a; + opt_t *o; + char c; + int i; + + a = (ipmon_action_t *)calloc(1, sizeof(*a)); + if (a == NULL) + return; + while ((o = olist) != NULL) { + /* + * Check to see if the same comparator is being used more than + * once per matching statement. + */ + for (i = 0; macflags[i][0]; i++) + if (macflags[i][0] == o->o_type) + break; + if (macflags[i][1] & a->ac_mflag) { + fprintf(stderr, "%s redfined on line %d\n", + yykeytostr(o->o_type), yylineNum); + if (o->o_str != NULL) + free(o->o_str); + olist = o->o_next; + free(o); + continue; + } + + a->ac_mflag |= macflags[i][1]; + + switch (o->o_type) + { + case IPM_DIRECTION : + a->ac_direction = o->o_num; + break; + case IPM_DSTIP : + a->ac_dip = o->o_ip.s_addr; + a->ac_dmsk = htonl(0xffffffff << (32 - o->o_num)); + break; + case IPM_DSTPORT : + a->ac_dport = htons(o->o_num); + break; + case IPM_EXECUTE : + a->ac_exec = o->o_str; + c = *o->o_str; + if (c== '"'|| c == '\'') { + if (o->o_str[strlen(o->o_str) - 1] == c) { + a->ac_run = strdup(o->o_str + 1); + a->ac_run[strlen(a->ac_run) - 1] ='\0'; + } else + a->ac_run = o->o_str; + } else + a->ac_run = o->o_str; + o->o_str = NULL; + break; + case IPM_INTERFACE : + a->ac_iface = o->o_str; + o->o_str = NULL; + break; + case IPM_GROUP : + if (o->o_str != NULL) + strncpy(a->ac_group, o->o_str, FR_GROUPLEN); + else + sprintf(a->ac_group, "%d", o->o_num); + break; + case IPM_LOGTAG : + a->ac_logtag = o->o_num; + break; + case IPM_NATTAG : + strncpy(a->ac_nattag, o->o_str, sizeof(a->ac_nattag)); + break; + case IPM_PACKET : + a->ac_packet = o->o_num; + break; + case IPM_PROTOCOL : + a->ac_proto = o->o_num; + break; + case IPM_RULE : + a->ac_rule = o->o_num; + break; + case IPM_RESULT : + if (!strcasecmp(o->o_str, "pass")) + a->ac_result = IPMR_PASS; + else if (!strcasecmp(o->o_str, "block")) + a->ac_result = IPMR_BLOCK; + else if (!strcasecmp(o->o_str, "nomatch")) + a->ac_result = IPMR_NOMATCH; + else if (!strcasecmp(o->o_str, "log")) + a->ac_result = IPMR_LOG; + break; + case IPM_SECOND : + a->ac_second = o->o_num; + break; + case IPM_SRCIP : + a->ac_sip = o->o_ip.s_addr; + a->ac_smsk = htonl(0xffffffff << (32 - o->o_num)); + break; + case IPM_SRCPORT : + a->ac_sport = htons(o->o_num); + break; + case IPM_SAVE : + if (a->ac_savefile != NULL) { + fprintf(stderr, "%s redfined on line %d\n", + yykeytostr(o->o_type), yylineNum); + break; + } + a->ac_savefile = strdup(o->o_str); + a->ac_savefp = fopen(o->o_str, "a"); + a->ac_dflag |= o->o_num & IPMDO_SAVERAW; + break; + case IPM_SYSLOG : + if (a->ac_syslog != 0) { + fprintf(stderr, "%s redfined on line %d\n", + yykeytostr(o->o_type), yylineNum); + break; + } + a->ac_syslog = 1; + break; + case IPM_TYPE : + a->ac_type = o->o_num; + break; + case IPM_WITH : + break; + default : + break; + } + + olist = o->o_next; + if (o->o_str != NULL) + free(o->o_str); + free(o); + } + a->ac_next = alist; + alist = a; +} + + +int check_action(buf, log, opts, lvl) +char *buf, *log; +int opts, lvl; +{ + ipmon_action_t *a; + struct timeval tv; + ipflog_t *ipf; + tcphdr_t *tcp; + iplog_t *ipl; + int matched; + u_long t1; + ip_t *ip; + + matched = 0; + ipl = (iplog_t *)buf; + ipf = (ipflog_t *)(ipl +1); + ip = (ip_t *)(ipf + 1); + tcp = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2)); + + for (a = alist; a != NULL; a = a->ac_next) { + if ((a->ac_mflag & IPMAC_DIRECTION) != 0) { + if (a->ac_direction == IPM_IN) { + if ((ipf->fl_flags & FR_INQUE) == 0) + continue; + } else if (a->ac_direction == IPM_OUT) { + if ((ipf->fl_flags & FR_OUTQUE) == 0) + continue; + } + } + + if ((a->ac_type != 0) && (a->ac_type != ipl->ipl_magic)) + continue; + + if ((a->ac_mflag & IPMAC_EVERY) != 0) { + gettimeofday(&tv, NULL); + t1 = tv.tv_sec - a->ac_lastsec; + if (tv.tv_usec <= a->ac_lastusec) + t1--; + if (a->ac_second != 0) { + if (t1 < a->ac_second) + continue; + a->ac_lastsec = tv.tv_sec; + a->ac_lastusec = tv.tv_usec; + } + + if (a->ac_packet != 0) { + if (a->ac_pktcnt == 0) + a->ac_pktcnt++; + else if (a->ac_pktcnt == a->ac_packet) { + a->ac_pktcnt = 0; + continue; + } else { + a->ac_pktcnt++; + continue; + } + } + } + + if ((a->ac_mflag & IPMAC_DSTIP) != 0) { + if ((ip->ip_dst.s_addr & a->ac_dmsk) != a->ac_dip) + continue; + } + + if ((a->ac_mflag & IPMAC_DSTPORT) != 0) { + if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) + continue; + if (tcp->th_dport != a->ac_dport) + continue; + } + + if ((a->ac_mflag & IPMAC_GROUP) != 0) { + if (strncmp(a->ac_group, ipf->fl_group, + FR_GROUPLEN) != 0) + continue; + } + + if ((a->ac_mflag & IPMAC_INTERFACE) != 0) { + if (strcmp(a->ac_iface, ipf->fl_ifname)) + continue; + } + + if ((a->ac_mflag & IPMAC_PROTOCOL) != 0) { + if (a->ac_proto != ip->ip_p) + continue; + } + + if ((a->ac_mflag & IPMAC_RESULT) != 0) { + if ((ipf->fl_flags & FF_LOGNOMATCH) != 0) { + if (a->ac_result != IPMR_NOMATCH) + continue; + } else if (FR_ISPASS(ipf->fl_flags)) { + if (a->ac_result != IPMR_PASS) + continue; + } else if (FR_ISBLOCK(ipf->fl_flags)) { + if (a->ac_result != IPMR_BLOCK) + continue; + } else { /* Log only */ + if (a->ac_result != IPMR_LOG) + continue; + } + } + + if ((a->ac_mflag & IPMAC_RULE) != 0) { + if (a->ac_rule != ipf->fl_rule) + continue; + } + + if ((a->ac_mflag & IPMAC_SRCIP) != 0) { + if ((ip->ip_src.s_addr & a->ac_smsk) != a->ac_sip) + continue; + } + + if ((a->ac_mflag & IPMAC_SRCPORT) != 0) { + if (ip->ip_p != IPPROTO_UDP && ip->ip_p != IPPROTO_TCP) + continue; + if (tcp->th_sport != a->ac_sport) + continue; + } + + if ((a->ac_mflag & IPMAC_LOGTAG) != 0) { + if (a->ac_logtag != ipf->fl_logtag) + continue; + } + + if ((a->ac_mflag & IPMAC_NATTAG) != 0) { + if (strncmp(a->ac_nattag, ipf->fl_nattag.ipt_tag, + IPFTAG_LEN) != 0) + continue; + } + + matched = 1; + + /* + * It matched so now execute the command + */ + if (a->ac_syslog != 0) { + syslog(lvl, "%s", log); + } + + if (a->ac_savefp != NULL) { + if (a->ac_dflag & IPMDO_SAVERAW) + fwrite(ipl, 1, ipl->ipl_dsize, a->ac_savefp); + else + fputs(log, a->ac_savefp); + } + + if (a->ac_exec != NULL) { + switch (fork()) + { + case 0 : + { + FILE *pi; + + pi = popen(a->ac_run, "w"); + if (pi != NULL) { + fprintf(pi, "%s\n", log); + if ((opts & OPT_HEXHDR) != 0) { + dumphex(pi, 0, buf, + sizeof(*ipl) + + sizeof(*ipf)); + } + if ((opts & OPT_HEXBODY) != 0) { + dumphex(pi, 0, (char *)ip, + ipf->fl_hlen + + ipf->fl_plen); + } + pclose(pi); + } + exit(1); + } + case -1 : + break; + default : + break; + } + } + } + + return matched; +} + + +static void free_action(a) +ipmon_action_t *a; +{ + if (a->ac_savefile != NULL) { + free(a->ac_savefile); + a->ac_savefile = NULL; + } + if (a->ac_savefp != NULL) { + fclose(a->ac_savefp); + a->ac_savefp = NULL; + } + if (a->ac_exec != NULL) { + free(a->ac_exec); + if (a->ac_run == a->ac_exec) + a->ac_run = NULL; + a->ac_exec = NULL; + } + if (a->ac_run != NULL) { + free(a->ac_run); + a->ac_run = NULL; + } + if (a->ac_iface != NULL) { + free(a->ac_iface); + a->ac_iface = NULL; + } + a->ac_next = NULL; + free(a); +} + + +int load_config(file) +char *file; +{ + ipmon_action_t *a; + FILE *fp; + char *s; + + s = getenv("YYDEBUG"); + if (s != NULL) + yydebug = atoi(s); + else + yydebug = 0; + + while ((a = alist) != NULL) { + alist = a->ac_next; + free_action(a); + } + + yylineNum = 1; + + (void) yysettab(yywords); + + fp = fopen(file, "r"); + if (!fp) { + perror("load_config:fopen:"); + return -1; + } + yyin = fp; + while (!feof(fp)) + yyparse(); + fclose(fp); + return 0; +} diff --git a/contrib/ipfilter/tools/ipnat.c b/contrib/ipfilter/tools/ipnat.c new file mode 100644 index 000000000000..fc17cea76f27 --- /dev/null +++ b/contrib/ipfilter/tools/ipnat.c @@ -0,0 +1,400 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + * + * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) + */ +#include +#include +#include +#include +#include +#if !defined(__SVR4) && !defined(__svr4__) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#define _KERNEL +#include +#undef _KERNEL +#include +#include +#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) +# include +# include +#endif +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#include +#include +#include +#include +#include +#if defined(linux) +# include +#else +# include +#endif +#include "ipf.h" +#include "ipl.h" +#include "kmem.h" + +#ifdef __hpux +# define nlist nlist64 +#endif + +#if defined(sun) && !SOLARIS2 +# define STRERROR(x) sys_errlist[x] +extern char *sys_errlist[]; +#else +# define STRERROR(x) strerror(x) +#endif + +#if !defined(lint) +static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipnat.c,v 1.24.2.1 2004/04/28 17:56:22 darrenr Exp"; +#endif + + +#if SOLARIS +#define bzero(a,b) memset(a,0,b) +#endif +int use_inet6 = 0; +char thishost[MAXHOSTNAMELEN]; + +extern char *optarg; + +void dostats __P((natstat_t *, int)), flushtable __P((int, int)); +void usage __P((char *)); +int main __P((int, char*[])); +void showhostmap __P((natstat_t *nsp)); +void natstat_dead __P((natstat_t *, char *)); + +int opts; + +void usage(name) +char *name; +{ + fprintf(stderr, "Usage: %s [-CFhlnrRsv] [-f filename]\n", name); + exit(1); +} + + +int main(argc, argv) +int argc; +char *argv[]; +{ + char *file, *core, *kernel; + natstat_t ns, *nsp; + int fd, c, mode; + ipfobj_t obj; + + fd = -1; + opts = 0; + nsp = &ns; + file = NULL; + core = NULL; + kernel = NULL; + mode = O_RDWR; + + while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1) + switch (c) + { + case 'C' : + opts |= OPT_CLEAR; + break; + case 'd' : + opts |= OPT_DEBUG; + break; + case 'f' : + file = optarg; + break; + case 'F' : + opts |= OPT_FLUSH; + break; + case 'h' : + opts |=OPT_HITS; + break; + case 'l' : + opts |= OPT_LIST; + mode = O_RDONLY; + break; + case 'M' : + core = optarg; + break; + case 'N' : + kernel = optarg; + break; + case 'n' : + opts |= OPT_DONOTHING; + mode = O_RDONLY; + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 'r' : + opts |= OPT_REMOVE; + break; + case 's' : + opts |= OPT_STAT; + mode = O_RDONLY; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + default : + usage(argv[0]); + } + + initparse(); + + if ((kernel != NULL) || (core != NULL)) { + (void) setgid(getgid()); + (void) setuid(getuid()); + } + + bzero((char *)&ns, sizeof(ns)); + + if ((opts & OPT_DONOTHING) == 0) { + if (checkrev(IPL_NAME) == -1) { + fprintf(stderr, "User/kernel version check failed\n"); + exit(1); + } + } + + + if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) { + if (openkmem(kernel, core) == -1) + exit(1); + + if (((fd = open(IPNAT_NAME, mode)) == -1) && + ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) { + (void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME, + STRERROR(errno)); + exit(1); + } + + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(*nsp); + obj.ipfo_type = IPFOBJ_NATSTAT; + obj.ipfo_ptr = (void *)nsp; + if (ioctl(fd, SIOCGNATS, &obj) == -1) { + perror("ioctl(SIOCGNATS)"); + exit(1); + } + (void) setgid(getgid()); + (void) setuid(getuid()); + } else if ((kernel != NULL) || (core != NULL)) { + if (openkmem(kernel, core) == -1) + exit(1); + + natstat_dead(nsp, kernel); + if (opts & (OPT_LIST|OPT_STAT)) + dostats(nsp, opts); + exit(0); + } + + if (opts & (OPT_FLUSH|OPT_CLEAR)) + flushtable(fd, opts); + if (file) { + ipnat_parsefile(fd, ipnat_addrule, ioctl, file); + } + if (opts & (OPT_LIST|OPT_STAT)) + dostats(nsp, opts); + return 0; +} + + +/* + * Read NAT statistic information in using a symbol table and memory file + * rather than doing ioctl's. + */ +void natstat_dead(nsp, kernel) +natstat_t *nsp; +char *kernel; +{ + struct nlist nat_nlist[10] = { + { "nat_table" }, /* 0 */ + { "nat_list" }, + { "maptable" }, + { "ipf_nattable_sz" }, + { "ipf_natrules_sz" }, + { "ipf_rdrrules_sz" }, /* 5 */ + { "ipf_hostmap_sz" }, + { "nat_instances" }, + { "ap_sess_list" }, + { NULL } + }; + void *tables[2]; + + if (nlist(kernel, nat_nlist) == -1) { + fprintf(stderr, "nlist error\n"); + return; + } + + /* + * Normally the ioctl copies all of these values into the structure + * for us, before returning it to userland, so here we must copy each + * one in individually. + */ + kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); + nsp->ns_table[0] = tables[0]; + nsp->ns_table[1] = tables[1]; + + kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, + sizeof(nsp->ns_list)); + kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value, + sizeof(nsp->ns_maptable)); + kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value, + sizeof(nsp->ns_nattab_sz)); + kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value, + sizeof(nsp->ns_rultab_sz)); + kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value, + sizeof(nsp->ns_rdrtab_sz)); + kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value, + sizeof(nsp->ns_hostmap_sz)); + kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, + sizeof(nsp->ns_instances)); + kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value, + sizeof(nsp->ns_apslist)); +} + + +/* + * Display NAT statistics. + */ +void dostats(nsp, opts) +natstat_t *nsp; +int opts; +{ + nat_t *np, nat; + ipnat_t ipn; + + /* + * Show statistics ? + */ + if (opts & OPT_STAT) { + printf("mapped\tin\t%lu\tout\t%lu\n", + nsp->ns_mapped[0], nsp->ns_mapped[1]); + printf("added\t%lu\texpired\t%lu\n", + nsp->ns_added, nsp->ns_expire); + printf("no memory\t%lu\tbad nat\t%lu\n", + nsp->ns_memfail, nsp->ns_badnat); + printf("inuse\t%lu\nrules\t%lu\n", + nsp->ns_inuse, nsp->ns_rules); + printf("wilds\t%u\n", nsp->ns_wilds); + if (opts & OPT_VERBOSE) + printf("table %p list %p\n", + nsp->ns_table, nsp->ns_list); + } + + /* + * Show list of NAT rules and NAT sessions ? + */ + if (opts & OPT_LIST) { + printf("List of active MAP/Redirect filters:\n"); + while (nsp->ns_list) { + if (kmemcpy((char *)&ipn, (long)nsp->ns_list, + sizeof(ipn))) { + perror("kmemcpy"); + break; + } + if (opts & OPT_HITS) + printf("%lu ", ipn.in_hits); + printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); + nsp->ns_list = ipn.in_next; + } + + printf("\nList of active sessions:\n"); + + for (np = nsp->ns_instances; np; np = nat.nat_next) { + if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) + break; + printactivenat(&nat, opts); + if (nat.nat_aps) + printaps(nat.nat_aps, opts); + } + + if (opts & OPT_VERBOSE) + showhostmap(nsp); + } +} + + +/* + * Display the active host mapping table. + */ +void showhostmap(nsp) +natstat_t *nsp; +{ + hostmap_t hm, *hmp, **maptable; + u_int hv; + + printf("\nList of active host mappings:\n"); + + maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) * + nsp->ns_hostmap_sz); + if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable, + sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) { + perror("kmemcpy (maptable)"); + return; + } + + for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) { + hmp = maptable[hv]; + + while (hmp) { + if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) { + perror("kmemcpy (hostmap)"); + return; + } + + printhostmap(&hm, hv); + hmp = hm.hm_next; + } + } + free(maptable); +} + + +/* + * Issue an ioctl to flush either the NAT rules table or the active mapping + * table or both. + */ +void flushtable(fd, opts) +int fd, opts; +{ + int n = 0; + + if (opts & OPT_FLUSH) { + n = 0; + if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) + perror("ioctl(SIOCFLNAT)"); + else + printf("%d entries flushed from NAT table\n", n); + } + + if (opts & OPT_CLEAR) { + n = 1; + if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) + perror("ioctl(SIOCCNATL)"); + else + printf("%d entries flushed from NAT list\n", n); + } +} diff --git a/contrib/ipfilter/tools/ipnat_y.y b/contrib/ipfilter/tools/ipnat_y.y new file mode 100644 index 000000000000..d3f18c66c4fb --- /dev/null +++ b/contrib/ipfilter/tools/ipnat_y.y @@ -0,0 +1,828 @@ +/* $NetBSD$ */ + +%{ +#ifdef __FreeBSD__ +# ifndef __FreeBSD_cc_version +# include +# else +# if __FreeBSD_cc_version < 430000 +# include +# endif +# endif +#endif +#include +#include +#include +#include +#include +#if !defined(__SVR4) && !defined(__GNUC__) +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#include +#include +#include +#include "ipf.h" +#include "netinet/ipl.h" +#include "ipnat_l.h" + +#define YYDEBUG 1 + +extern void yyerror __P((char *)); +extern int yyparse __P((void)); +extern int yylex __P((void)); +extern int yydebug; +extern FILE *yyin; +extern int yylineNum; + +static ipnat_t *nattop = NULL; +static ipnat_t *nat = NULL; +static int natfd = -1; +static ioctlfunc_t natioctlfunc = NULL; +static addfunc_t nataddfunc = NULL; + +static void newnatrule __P((void)); +static void setnatproto __P((int)); + +%} +%union { + char *str; + u_32_t num; + struct in_addr ipa; + frentry_t fr; + frtuc_t *frt; + u_short port; + struct { + u_short p1; + u_short p2; + int pc; + } pc; + struct { + struct in_addr a; + struct in_addr m; + } ipp; + union i6addr ip6; +}; + +%token YY_NUMBER YY_HEX +%token YY_STR +%token YY_COMMENT +%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT +%token YY_RANGE_OUT YY_RANGE_IN +%token YY_IPV6 + +%token IPNY_MAPBLOCK IPNY_RDR IPNY_PORT IPNY_PORTS IPNY_AUTO IPNY_RANGE +%token IPNY_MAP IPNY_BIMAP IPNY_FROM IPNY_TO IPNY_MASK IPNY_PORTMAP IPNY_ANY +%token IPNY_ROUNDROBIN IPNY_FRAG IPNY_AGE IPNY_ICMPIDMAP IPNY_PROXY +%token IPNY_TCP IPNY_UDP IPNY_TCPUDP IPNY_STICKY IPNY_MSSCLAMP IPNY_TAG +%token IPNY_TLATE +%type portspec +%type hexnumber compare range proto +%type hostname ipv4 +%type addr nummask rhaddr +%type portstuff +%% +file: line + | assign + | file line + | file assign + ; + +line: xx rule { while ((nat = nattop) != NULL) { + nattop = nat->in_next; + (*nataddfunc)(natfd, natioctlfunc, nat); + free(nat); + } + resetlexer(); + } + | YY_COMMENT + ; + +assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); + resetlexer(); + free($1); + free($3); + } + ; + +assigning: + '=' { yyvarnext = 1; } + ; + +xx: { newnatrule(); } + ; + +rule: map eol + | mapblock eol + | redir eol + ; + +eol: | ';' + ; + +map: mapit ifnames addr IPNY_TLATE rhaddr proxy mapoptions + { nat->in_v = 4; + nat->in_inip = $3.a.s_addr; + nat->in_inmsk = $3.m.s_addr; + nat->in_outip = $5.a.s_addr; + nat->in_outmsk = $5.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + if ((nat->in_flags & IPN_TCPUDP) == 0) + setnatproto(nat->in_p); + if (((nat->in_redir & NAT_MAPBLK) != 0) || + ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) + nat_setgroupmap(nat); + } + | mapit ifnames addr IPNY_TLATE rhaddr mapport mapoptions + { nat->in_v = 4; + nat->in_inip = $3.a.s_addr; + nat->in_inmsk = $3.m.s_addr; + nat->in_outip = $5.a.s_addr; + nat->in_outmsk = $5.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0) + setnatproto(nat->in_p); + if (((nat->in_redir & NAT_MAPBLK) != 0) || + ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) + nat_setgroupmap(nat); + } + | mapit ifnames mapfrom IPNY_TLATE rhaddr proxy mapoptions + { nat->in_v = 4; + nat->in_outip = $5.a.s_addr; + nat->in_outmsk = $5.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + if ((nat->in_flags & IPN_TCPUDP) == 0) + setnatproto(nat->in_p); + if (((nat->in_redir & NAT_MAPBLK) != 0) || + ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) + nat_setgroupmap(nat); + } + | mapit ifnames mapfrom IPNY_TLATE rhaddr mapport mapoptions + { nat->in_v = 4; + nat->in_outip = $5.a.s_addr; + nat->in_outmsk = $5.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + if ((nat->in_flags & IPN_TCPUDPICMPQ) == 0) + setnatproto(nat->in_p); + if (((nat->in_redir & NAT_MAPBLK) != 0) || + ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) + nat_setgroupmap(nat); + } + ; + +mapblock: + mapblockit ifnames addr IPNY_TLATE addr ports mapoptions + { nat->in_v = 4; + nat->in_inip = $3.a.s_addr; + nat->in_inmsk = $3.m.s_addr; + nat->in_outip = $5.a.s_addr; + nat->in_outmsk = $5.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + if ((nat->in_flags & IPN_TCPUDP) == 0) + setnatproto(nat->in_p); + if (((nat->in_redir & NAT_MAPBLK) != 0) || + ((nat->in_flags & IPN_AUTOPORTMAP) != 0)) + nat_setgroupmap(nat); + } + ; + +redir: rdrit ifnames addr dport IPNY_TLATE dip nport setproto rdroptions + { nat->in_v = 4; + nat->in_outip = $3.a.s_addr; + nat->in_outmsk = $3.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + if ((nat->in_p == 0) && + ((nat->in_flags & IPN_TCPUDP) == 0) && + (nat->in_pmin != 0 || + nat->in_pmax != 0 || + nat->in_pnext != 0)) + setnatproto(IPPROTO_TCP); + } + | rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions + { nat->in_v = 4; + if ((nat->in_p == 0) && + ((nat->in_flags & IPN_TCPUDP) == 0) && + (nat->in_pmin != 0 || + nat->in_pmax != 0 || + nat->in_pnext != 0)) + setnatproto(IPPROTO_TCP); + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + } + | rdrit ifnames addr IPNY_TLATE dip setproto rdroptions + { nat->in_v = 4; + nat->in_outip = $3.a.s_addr; + nat->in_outmsk = $3.m.s_addr; + if (nat->in_ifnames[1][0] == '\0') + strncpy(nat->in_ifnames[1], + nat->in_ifnames[0], + sizeof(nat->in_ifnames[0])); + } + ; + +proxy: | IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto + { strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); + if (nat->in_dcmp == 0) { + nat->in_dport = htons($3); + } else if ($3 != nat->in_dport) { + yyerror("proxy port numbers not consistant"); + } + setnatproto($6); + free($4); + } + | IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto + { int pnum; + strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel)); + pnum = getportproto($3, $6); + if (pnum == -1) + yyerror("invalid port number"); + nat->in_dport = pnum; + setnatproto($6); + free($3); + free($4); + } + ; + +setproto: + | proto { if (nat->in_p != 0 || + nat->in_flags & IPN_TCPUDP) + yyerror("protocol set twice"); + setnatproto($1); + } + | IPNY_TCPUDP { if (nat->in_p != 0 || + nat->in_flags & IPN_TCPUDP) + yyerror("protocol set twice"); + nat->in_flags |= IPN_TCPUDP; + nat->in_p = 0; + } + | IPNY_TCP '/' IPNY_UDP { if (nat->in_p != 0 || + nat->in_flags & IPN_TCPUDP) + yyerror("protocol set twice"); + nat->in_flags |= IPN_TCPUDP; + nat->in_p = 0; + } + ; + +rhaddr: addr { $$.a = $1.a; $$.m = $1.m; } + | IPNY_RANGE ipv4 '-' ipv4 + { $$.a = $2; $$.m = $4; + nat->in_flags |= IPN_IPRANGE; } + ; + +dip: + hostname { nat->in_inip = $1.s_addr; + nat->in_inmsk = 0xffffffff; } + | hostname ',' hostname { nat->in_flags |= IPN_SPLIT; + nat->in_inip = $1.s_addr; + nat->in_inmsk = $3.s_addr; } + ; + +portspec: + YY_NUMBER { if ($1 > 65535) /* Unsigned */ + yyerror("invalid port number"); + else + $$ = $1; + } + | YY_STR { if (getport(NULL, $1, &($$)) == -1) + yyerror("invalid port number"); + $$ = ntohs($$); + } + ; + +dport: | IPNY_PORT portspec { nat->in_pmin = htons($2); + nat->in_pmax = htons($2); } + | IPNY_PORT portspec '-' portspec { nat->in_pmin = htons($2); + nat->in_pmax = htons($4); } + | IPNY_PORT portspec ':' portspec { nat->in_pmin = htons($2); + nat->in_pmax = htons($4); } + ; + +nport: IPNY_PORT portspec { nat->in_pnext = htons($2); } + | IPNY_PORT '=' portspec { nat->in_pnext = htons($3); + nat->in_flags |= IPN_FIXEDDPORT; + } + ; + +ports: | IPNY_PORTS YY_NUMBER { nat->in_pmin = $2; } + | IPNY_PORTS IPNY_AUTO { nat->in_flags |= IPN_AUTOPORTMAP; } + ; + +mapit: IPNY_MAP { nat->in_redir = NAT_MAP; } + | IPNY_BIMAP { nat->in_redir = NAT_BIMAP; } + ; + +rdrit: IPNY_RDR { nat->in_redir = NAT_REDIRECT; } + ; + +mapblockit: + IPNY_MAPBLOCK { nat->in_redir = NAT_MAPBLK; } + ; + +mapfrom: + from sobject IPNY_TO dobject + | from sobject '!' IPNY_TO dobject + { nat->in_flags |= IPN_NOTDST; } + ; + +rdrfrom: + from sobject IPNY_TO dobject + | '!' from sobject IPNY_TO dobject + { nat->in_flags |= IPN_NOTSRC; } + ; + +from: IPNY_FROM { nat->in_flags |= IPN_FILTER; } + ; + +ifnames: + ifname + | ifname ',' otherifname + ; + +ifname: YY_STR { strncpy(nat->in_ifnames[0], $1, + sizeof(nat->in_ifnames[0])); + nat->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; + free($1); + } + ; + +otherifname: + YY_STR { strncpy(nat->in_ifnames[1], $1, + sizeof(nat->in_ifnames[1])); + nat->in_ifnames[1][LIFNAMSIZ - 1] = '\0'; + free($1); + } + ; + +mapport: + IPNY_PORTMAP tcpudp portspec ':' portspec + { nat->in_pmin = htons($3); + nat->in_pmax = htons($5); + } + | IPNY_PORTMAP tcpudp IPNY_AUTO + { nat->in_flags |= IPN_AUTOPORTMAP; + nat->in_pmin = htons(1024); + nat->in_pmax = htons(65535); + } + | IPNY_ICMPIDMAP YY_STR YY_NUMBER ':' YY_NUMBER + { if (strcmp($2, "icmp") != 0) { + yyerror("icmpidmap not followed by icmp"); + } + free($2); + if ($3 < 0 || $3 > 65535) + yyerror("invalid ICMP Id number"); + if ($5 < 0 || $5 > 65535) + yyerror("invalid ICMP Id number"); + nat->in_flags = IPN_ICMPQUERY; + nat->in_pmin = htons($3); + nat->in_pmax = htons($5); + } + ; + +sobject: + saddr + | saddr IPNY_PORT portstuff { nat->in_sport = $3.p1; + nat->in_stop = $3.p2; + nat->in_scmp = $3.pc; } + ; + +saddr: addr { if (nat->in_redir == NAT_REDIRECT) { + nat->in_srcip = $1.a.s_addr; + nat->in_srcmsk = $1.m.s_addr; + } else { + nat->in_inip = $1.a.s_addr; + nat->in_inmsk = $1.m.s_addr; + } + } + ; + +dobject: + daddr + | daddr IPNY_PORT portstuff { nat->in_dport = $3.p1; + nat->in_dtop = $3.p2; + nat->in_dcmp = $3.pc; + if (nat->in_redir == NAT_REDIRECT) + nat->in_pmin = htons($3.p1); + } + ; + +daddr: addr { if (nat->in_redir == NAT_REDIRECT) { + nat->in_outip = $1.a.s_addr; + nat->in_outmsk = $1.m.s_addr; + } else { + nat->in_srcip = $1.a.s_addr; + nat->in_srcmsk = $1.m.s_addr; + } + } + ; + +addr: IPNY_ANY { $$.a.s_addr = 0; $$.m.s_addr = 0; } + | nummask { $$.a = $1.a; $$.m = $1.m; + $$.a.s_addr &= $$.m.s_addr; } + | hostname '/' ipv4 { $$.a = $1; $$.m = $3; + $$.a.s_addr &= $$.m.s_addr; } + | hostname '/' hexnumber { $$.a = $1; $$.m.s_addr = $3; + $$.a.s_addr &= $$.m.s_addr; } + | hostname IPNY_MASK ipv4 { $$.a = $1; $$.m = $3; + $$.a.s_addr &= $$.m.s_addr; } + | hostname IPNY_MASK hexnumber { $$.a = $1; $$.m.s_addr = $3; + $$.a.s_addr &= $$.m.s_addr; } + ; + +nummask: + hostname { $$.a = $1; + $$.m.s_addr = 0xffffffff; } + | hostname '/' YY_NUMBER { $$.a = $1; + ntomask(4, $3, &$$.m.s_addr); } + ; + +portstuff: + compare portspec { $$.pc = $1; $$.p1 = $2; } + | portspec range portspec { $$.pc = $2; $$.p1 = $1; $$.p1 = $3; } + ; + +mapoptions: + rr frag age mssclamp nattag setproto + ; + +rdroptions: + rr frag age sticky mssclamp rdrproxy nattag + ; + +nattag: | IPNY_TAG YY_STR { strncpy(nat->in_tag.ipt_tag, $2, + sizeof(nat->in_tag.ipt_tag)); + } +rr: | IPNY_ROUNDROBIN { nat->in_flags |= IPN_ROUNDR; } + ; + +frag: | IPNY_FRAG { nat->in_flags |= IPN_FRAG; } + ; + +age: | IPNY_AGE YY_NUMBER { nat->in_age[0] = $2; + nat->in_age[1] = $2; } + | IPNY_AGE YY_NUMBER '/' YY_NUMBER { nat->in_age[0] = $2; + nat->in_age[1] = $4; } + ; + +sticky: | IPNY_STICKY { if (!(nat->in_flags & IPN_ROUNDR) && + !(nat->in_flags & IPN_SPLIT)) { + fprintf(stderr, + "'sticky' for use with round-robin/IP splitting only\n"); + } else + nat->in_flags |= IPN_STICKY; + } + ; + +mssclamp: + | IPNY_MSSCLAMP YY_NUMBER { nat->in_mssclamp = $2; } + ; + +tcpudp: | IPNY_TCP { setnatproto(IPPROTO_TCP); } + | IPNY_UDP { setnatproto(IPPROTO_UDP); } + | IPNY_TCPUDP { nat->in_flags |= IPN_TCPUDP; + nat->in_p = 0; + } + | IPNY_TCP '/' IPNY_UDP { nat->in_flags |= IPN_TCPUDP; + nat->in_p = 0; + } + ; + +rdrproxy: + IPNY_PROXY YY_STR + { strncpy(nat->in_plabel, $2, + sizeof(nat->in_plabel)); + nat->in_dport = nat->in_pnext; + nat->in_dport = htons(nat->in_dport); + free($2); + } + | proxy { if (nat->in_plabel[0] != '\0') { + nat->in_pmin = nat->in_dport; + nat->in_pmax = nat->in_pmin; + nat->in_pnext = nat->in_pmin; + } + } + ; + +proto: YY_NUMBER { $$ = $1; } + | IPNY_TCP { $$ = IPPROTO_TCP; } + | IPNY_UDP { $$ = IPPROTO_UDP; } + | YY_STR { $$ = getproto($1); free($1); } + ; + +hexnumber: + YY_HEX { $$ = $1; } + ; + +hostname: + YY_STR { if (gethost($1, &$$.s_addr) == -1) + fprintf(stderr, + "Unknown host '%s'\n", + $1); + free($1); + } + | YY_NUMBER { $$.s_addr = htonl($1); } + | ipv4 { $$.s_addr = $1.s_addr; } + ; + +compare: + '=' { $$ = FR_EQUAL; } + | YY_CMP_EQ { $$ = FR_EQUAL; } + | YY_CMP_NE { $$ = FR_NEQUAL; } + | YY_CMP_LT { $$ = FR_LESST; } + | YY_CMP_LE { $$ = FR_LESSTE; } + | YY_CMP_GT { $$ = FR_GREATERT; } + | YY_CMP_GE { $$ = FR_GREATERTE; } + +range: + YY_RANGE_OUT { $$ = FR_OUTRANGE; } + | YY_RANGE_IN { $$ = FR_INRANGE; } + ; + +ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER + { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { + yyerror("Invalid octet string for IP address"); + return 0; + } + $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; + $$.s_addr = htonl($$.s_addr); + } + ; + +%% + + +static wordtab_t yywords[] = { + { "age", IPNY_AGE }, + { "any", IPNY_ANY }, + { "auto", IPNY_AUTO }, + { "bimap", IPNY_BIMAP }, + { "frag", IPNY_FRAG }, + { "from", IPNY_FROM }, + { "icmpidmap", IPNY_ICMPIDMAP }, + { "mask", IPNY_MASK }, + { "map", IPNY_MAP }, + { "map-block", IPNY_MAPBLOCK }, + { "mssclamp", IPNY_MSSCLAMP }, + { "netmask", IPNY_MASK }, + { "port", IPNY_PORT }, + { "portmap", IPNY_PORTMAP }, + { "ports", IPNY_PORTS }, + { "proxy", IPNY_PROXY }, + { "range", IPNY_RANGE }, + { "rdr", IPNY_RDR }, + { "round-robin",IPNY_ROUNDROBIN }, + { "sticky", IPNY_STICKY }, + { "tag", IPNY_TAG }, + { "tcp", IPNY_TCP }, + { "tcpudp", IPNY_TCPUDP }, + { "to", IPNY_TO }, + { "udp", IPNY_UDP }, + { "-", '-' }, + { "->", IPNY_TLATE }, + { "eq", YY_CMP_EQ }, + { "ne", YY_CMP_NE }, + { "lt", YY_CMP_LT }, + { "gt", YY_CMP_GT }, + { "le", YY_CMP_LE }, + { "ge", YY_CMP_GE }, + { NULL, 0 } +}; + + +int ipnat_parsefile(fd, addfunc, ioctlfunc, filename) +int fd; +addfunc_t addfunc; +ioctlfunc_t ioctlfunc; +char *filename; +{ + FILE *fp = NULL; + char *s; + + (void) yysettab(yywords); + + s = getenv("YYDEBUG"); + if (s) + yydebug = atoi(s); + else + yydebug = 0; + + if (strcmp(filename, "-")) { + fp = fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "fopen(%s) failed: %s\n", filename, + STRERROR(errno)); + return -1; + } + } else + fp = stdin; + + while (ipnat_parsesome(fd, addfunc, ioctlfunc, fp) == 1) + ; + if (fp != NULL) + fclose(fp); + return 0; +} + + +int ipnat_parsesome(fd, addfunc, ioctlfunc, fp) +int fd; +addfunc_t addfunc; +ioctlfunc_t ioctlfunc; +FILE *fp; +{ + char *s; + int i; + + yylineNum = 1; + + natfd = fd; + nataddfunc = addfunc; + natioctlfunc = ioctlfunc; + + if (feof(fp)) + return 0; + i = fgetc(fp); + if (i == EOF) + return 0; + if (ungetc(i, fp) == EOF) + return 0; + if (feof(fp)) + return 0; + s = getenv("YYDEBUG"); + if (s) + yydebug = atoi(s); + else + yydebug = 0; + + yyin = fp; + yyparse(); + return 1; +} + + +static void newnatrule() +{ + ipnat_t *n; + + n = calloc(1, sizeof(*n)); + if (n == NULL) + return; + + if (nat == NULL) + nattop = nat = n; + else { + nat->in_next = n; + nat = n; + } +} + + +static void setnatproto(p) +int p; +{ + nat->in_p = p; + + switch (p) + { + case IPPROTO_TCP : + nat->in_flags |= IPN_TCP; + nat->in_flags &= ~IPN_UDP; + break; + case IPPROTO_UDP : + nat->in_flags |= IPN_UDP; + nat->in_flags &= ~IPN_TCP; + break; + case IPPROTO_ICMP : + nat->in_flags &= ~IPN_TCPUDP; + if (!(nat->in_flags & IPN_ICMPQUERY)) { + nat->in_dcmp = 0; + nat->in_scmp = 0; + nat->in_pmin = 0; + nat->in_pmax = 0; + nat->in_pnext = 0; + } + break; + default : + if ((nat->in_redir & NAT_MAPBLK) == 0) { + nat->in_flags &= ~IPN_TCPUDP; + nat->in_dcmp = 0; + nat->in_scmp = 0; + nat->in_pmin = 0; + nat->in_pmax = 0; + nat->in_pnext = 0; + } + break; + } + + if ((nat->in_flags & (IPN_TCPUDP|IPN_FIXEDDPORT)) == IPN_FIXEDDPORT) + nat->in_flags &= ~IPN_FIXEDDPORT; +} + + +void ipnat_addrule(fd, ioctlfunc, ptr) +int fd; +ioctlfunc_t ioctlfunc; +void *ptr; +{ + ioctlcmd_t add, del; + ipfobj_t obj; + ipnat_t *ipn; + + ipn = ptr; + bzero((char *)&obj, sizeof(obj)); + obj.ipfo_rev = IPFILTER_VERSION; + obj.ipfo_size = sizeof(ipnat_t); + obj.ipfo_type = IPFOBJ_IPNAT; + obj.ipfo_ptr = ptr; + add = 0; + del = 0; + + if ((opts & OPT_DONOTHING) != 0) + fd = -1; + + if (opts & OPT_ZERORULEST) { + add = SIOCZRLST; + } else if (opts & OPT_INACTIVE) { + add = SIOCADNAT; + del = SIOCRMNAT; + } else { + add = SIOCADNAT; + del = SIOCRMNAT; + } + + if (ipn && (opts & OPT_VERBOSE)) + printnat(ipn, opts); + + if (opts & OPT_DEBUG) + binprint(ipn, sizeof(*ipn)); + + if ((opts & OPT_ZERORULEST) != 0) { + if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { + if ((opts & OPT_DONOTHING) == 0) { + fprintf(stderr, "%d:", yylineNum); + perror("ioctl(SIOCZRLST)"); + } + } else { +#ifdef USE_QUAD_T +/* + printf("hits %qd bytes %qd ", + (long long)fr->fr_hits, + (long long)fr->fr_bytes); +*/ +#else +/* + printf("hits %ld bytes %ld ", + fr->fr_hits, fr->fr_bytes); +*/ +#endif + printnat(ipn, opts); + } + } else if ((opts & OPT_REMOVE) != 0) { + if ((*ioctlfunc)(fd, del, (void *)&obj) == -1) { + if ((opts & OPT_DONOTHING) == 0) { + fprintf(stderr, "%d:", yylineNum); + perror("ioctl(delete nat rule)"); + } + } + } else { + if ((*ioctlfunc)(fd, add, (void *)&obj) == -1) { + if ((opts & OPT_DONOTHING) == 0) { + fprintf(stderr, "%d:", yylineNum); + perror("ioctl(add/insert nat rule)"); + } + } + } +} diff --git a/contrib/ipfilter/tools/ippool.c b/contrib/ipfilter/tools/ippool.c new file mode 100644 index 000000000000..7122c9443fd1 --- /dev/null +++ b/contrib/ipfilter/tools/ippool.c @@ -0,0 +1,700 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#include +#include +#include +#include +#if defined(BSD) && (BSD >= 199306) +# include +#endif +#include + +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" +#include "netinet/ip_htable.h" +#include "kmem.h" + + +extern int ippool_yyparse __P((void)); +extern int ippool_yydebug; +extern FILE *ippool_yyin; +extern char *optarg; +extern int lineNum; + +void showpools __P((ip_pool_stat_t *)); +void usage __P((char *)); +int main __P((int, char **)); +int poolcommand __P((int, int, char *[])); +int poolnodecommand __P((int, int, char *[])); +int loadpoolfile __P((int, char *[], char *)); +int poollist __P((int, char *[])); +int poolflush __P((int, char *[])); +int poolstats __P((int, char *[])); +int gettype __P((char *, u_int *)); +int getrole __P((char *)); + +int opts = 0; +int fd = -1; +int use_inet6 = 0; + + +void usage(prog) +char *prog; +{ + fprintf(stderr, "Usage:\t%s\n", prog); + fprintf(stderr, "\t\t\t-a [-dnv] [-m ] [-o ] -i [/netmask]\n"); + fprintf(stderr, "\t\t\t-A [-dnv] [-m ] [-o ] [-S ] [-t ]\n"); + fprintf(stderr, "\t\t\t-f [-dnuv]\n"); + fprintf(stderr, "\t\t\t-F [-dv] [-o ] [-t ]\n"); + fprintf(stderr, "\t\t\t-l [-dv] [-m ] [-t ]\n"); + fprintf(stderr, "\t\t\t-r [-dnv] [-m ] [-o ] -i [/netmask]\n"); + fprintf(stderr, "\t\t\t-R [-dnv] [-m ] [-o ] [-t ]\n"); + fprintf(stderr, "\t\t\t-s [-dtv] [-M ] [-N ]\n"); + exit(1); +} + + +int main(argc, argv) +int argc; +char *argv[]; +{ + int err; + + if (argc < 2) + usage(argv[0]); + + switch (getopt(argc, argv, "aAf:FlrRs")) + { + case 'a' : + err = poolnodecommand(0, argc, argv); + break; + case 'A' : + err = poolcommand(0, argc, argv); + break; + case 'f' : + err = loadpoolfile(argc, argv, optarg); + break; + case 'F' : + err = poolflush(argc, argv); + break; + case 'l' : + err = poollist(argc, argv); + break; + case 'r' : + err = poolnodecommand(1, argc, argv); + break; + case 'R' : + err = poolcommand(1, argc, argv); + break; + case 's' : + err = poolstats(argc, argv); + break; + default : + exit(1); + } + + return err; +} + + +int poolnodecommand(remove, argc, argv) +int remove, argc; +char *argv[]; +{ + char *poolname = NULL, *s; + int err, c, ipset, role; + ip_pool_node_t node; + struct in_addr mask; + + ipset = 0; + role = IPL_LOGIPF; + bzero((char *)&node, sizeof(node)); + + while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + ippool_yydebug++; + break; + case 'i' : + s = strchr(optarg, '/'); + if (s == NULL) + mask.s_addr = 0xffffffff; + else if (strchr(s, '.') == NULL) { + if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0) + return -1; + } else { + mask.s_addr = inet_addr(s + 1); + } + if (s != NULL) + *s = '\0'; + ipset = 1; + node.ipn_addr.adf_len = sizeof(node.ipn_addr); + node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg); + node.ipn_mask.adf_len = sizeof(node.ipn_mask); + node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr; + break; + case 'm' : + poolname = optarg; + break; + case 'n' : + opts |= OPT_DONOTHING; + break; + case 'o' : + role = getrole(optarg); + if (role == IPL_LOGNONE) + return -1; + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (opts & OPT_DEBUG) + fprintf(stderr, "poolnodecommand: opts = %#x\n", opts); + + if (ipset == 0) + return -1; + if (poolname == NULL) { + fprintf(stderr, "poolname not given with add/remove node\n"); + return -1; + } + + if (remove == 0) + err = load_poolnode(0, poolname, &node, ioctl); + else + err = remove_poolnode(0, poolname, &node, ioctl); + return err; +} + + +int poolcommand(remove, argc, argv) +int remove, argc; +char *argv[]; +{ + int type, role, c, err; + char *poolname; + iphtable_t iph; + ip_pool_t pool; + + err = 1; + role = 0; + type = 0; + poolname = NULL; + role = IPL_LOGIPF; + bzero((char *)&iph, sizeof(iph)); + bzero((char *)&pool, sizeof(pool)); + + while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + ippool_yydebug++; + break; + case 'm' : + poolname = optarg; + break; + case 'n' : + opts |= OPT_DONOTHING; + break; + case 'o' : + role = getrole(optarg); + if (role == IPL_LOGNONE) { + fprintf(stderr, "unknown role '%s'\n", optarg); + return -1; + } + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 'S' : + iph.iph_seed = atoi(optarg); + break; + case 't' : + type = gettype(optarg, &iph.iph_type); + if (type == IPLT_NONE) { + fprintf(stderr, "unknown type '%s'\n", optarg); + return -1; + } + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (opts & OPT_DEBUG) + fprintf(stderr, "poolcommand: opts = %#x\n", opts); + + if (poolname == NULL) { + fprintf(stderr, "poolname not given with add/remove pool\n"); + return -1; + } + + if (type == IPLT_HASH) { + strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); + iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; + iph.iph_unit = role; + } else if (type == IPLT_POOL) { + strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); + pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; + pool.ipo_unit = role; + } + + if (remove == 0) { + switch (type) + { + case IPLT_HASH : + err = load_hash(&iph, NULL, ioctl); + break; + case IPLT_POOL : + err = load_pool(&pool, ioctl); + break; + } + } else { + switch (type) + { + case IPLT_HASH : + err = remove_hash(&iph, ioctl); + break; + case IPLT_POOL : + err = remove_pool(&pool, ioctl); + break; + } + } + return err; +} + + +int loadpoolfile(argc, argv, infile) +int argc; +char *argv[], *infile; +{ + int c; + + infile = optarg; + + while ((c = getopt(argc, argv, "dnRuv")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + ippool_yydebug++; + break; + case 'n' : + opts |= OPT_DONOTHING; + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 'u' : + opts |= OPT_REMOVE; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (opts & OPT_DEBUG) + fprintf(stderr, "loadpoolfile: opts = %#x\n", opts); + + if (!(opts & OPT_DONOTHING) && (fd == -1)) { + fd = open(IPLOOKUP_NAME, O_RDWR); + if (fd == -1) { + perror("open(IPLOOKUP_NAME)"); + exit(1); + } + } + + if (ippool_parsefile(fd, infile, ioctl) != 0) + return -1; + return 0; +} + + +int poollist(argc, argv) +int argc; +char *argv[]; +{ + char *kernel, *core, *poolname; + int c, role, type, live_kernel; + ip_pool_stat_t *plstp, plstat; + iphtstat_t *htstp, htstat; + iphtable_t *hptr; + iplookupop_t op; + ip_pool_t *ptr; + + core = NULL; + kernel = NULL; + live_kernel = 1; + type = IPLT_ALL; + poolname = NULL; + role = IPL_LOGALL; + + while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + break; + case 'm' : + poolname = optarg; + break; + case 'M' : + live_kernel = 0; + core = optarg; + break; + case 'N' : + live_kernel = 0; + kernel = optarg; + break; + case 'o' : + role = getrole(optarg); + if (role == IPL_LOGNONE) { + fprintf(stderr, "unknown role '%s'\n", optarg); + return -1; + } + break; + case 'R' : + opts |= OPT_NORESOLVE; + break; + case 't' : + type = gettype(optarg, NULL); + if (type == IPLT_NONE) { + fprintf(stderr, "unknown type '%s'\n", optarg); + return -1; + } + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (opts & OPT_DEBUG) + fprintf(stderr, "poollist: opts = %#x\n", opts); + + if (!(opts & OPT_DONOTHING) && (fd == -1)) { + fd = open(IPLOOKUP_NAME, O_RDWR); + if (fd == -1) { + perror("open(IPLOOKUP_NAME)"); + exit(1); + } + } + + bzero((char *)&op, sizeof(op)); + if (poolname != NULL) { + strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); + op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; + } + op.iplo_unit = role; + + if (openkmem(kernel, core) == -1) + exit(-1); + + if (type == IPLT_ALL || type == IPLT_POOL) { + plstp = &plstat; + op.iplo_type = IPLT_POOL; + op.iplo_size = sizeof(plstat); + op.iplo_struct = &plstat; + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + perror("ioctl(SIOCLOOKUPSTAT)"); + return -1; + } + + if (role != IPL_LOGALL) { + ptr = plstp->ipls_list[role]; + while (ptr != NULL) { + ptr = printpool(ptr, kmemcpywrap, poolname, + opts); + } + } else { + for (role = 0; role <= IPL_LOGMAX; role++) { + ptr = plstp->ipls_list[role]; + while (ptr != NULL) { + ptr = printpool(ptr, kmemcpywrap, + poolname, opts); + } + } + role = IPL_LOGALL; + } + } + if (type == IPLT_ALL || type == IPLT_HASH) { + htstp = &htstat; + op.iplo_type = IPLT_HASH; + op.iplo_size = sizeof(htstat); + op.iplo_struct = &htstat; + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + perror("ioctl(SIOCLOOKUPSTAT)"); + return -1; + } + + if (role != IPL_LOGALL) { + hptr = htstp->iphs_tables; + while (hptr != NULL) { + hptr = printhash(hptr, kmemcpywrap, + poolname, opts); + } + } else { + for (role = 0; role <= IPL_LOGMAX; role++) { + hptr = htstp->iphs_tables; + while (hptr != NULL) { + hptr = printhash(hptr, kmemcpywrap, + poolname, opts); + } + + op.iplo_unit = role; + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + perror("ioctl(SIOCLOOKUPSTAT)"); + return -1; + } + } + } + } + return 0; +} + + +int poolstats(argc, argv) +int argc; +char *argv[]; +{ + int c, type, role, live_kernel; + ip_pool_stat_t plstat; + char *kernel, *core; + iphtstat_t htstat; + iplookupop_t op; + + core = NULL; + kernel = NULL; + live_kernel = 1; + type = IPLT_ALL; + role = IPL_LOGALL; + + bzero((char *)&op, sizeof(op)); + + while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + break; + case 'M' : + live_kernel = 0; + core = optarg; + break; + case 'N' : + live_kernel = 0; + kernel = optarg; + break; + case 'o' : + role = getrole(optarg); + if (role == IPL_LOGNONE) { + fprintf(stderr, "unknown role '%s'\n", optarg); + return -1; + } + break; + case 't' : + type = gettype(optarg, NULL); + if (type != IPLT_POOL) { + fprintf(stderr, + "-s not supported for this type yet\n"); + return -1; + } + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (opts & OPT_DEBUG) + fprintf(stderr, "poolstats: opts = %#x\n", opts); + + if (!(opts & OPT_DONOTHING) && (fd == -1)) { + fd = open(IPLOOKUP_NAME, O_RDWR); + if (fd == -1) { + perror("open(IPLOOKUP_NAME)"); + exit(1); + } + } + + if (type == IPLT_ALL || type == IPLT_POOL) { + op.iplo_type = IPLT_POOL; + op.iplo_struct = &plstat; + op.iplo_size = sizeof(plstat); + if (!(opts & OPT_DONOTHING)) { + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + perror("ioctl(SIOCLOOKUPSTAT)"); + return -1; + } + printf("Pools:\t%lu\n", plstat.ipls_pools); + printf("Nodes:\t%lu\n", plstat.ipls_nodes); + } + } + + if (type == IPLT_ALL || type == IPLT_HASH) { + op.iplo_type = IPLT_HASH; + op.iplo_struct = &htstat; + op.iplo_size = sizeof(htstat); + if (!(opts & OPT_DONOTHING)) { + c = ioctl(fd, SIOCLOOKUPSTAT, &op); + if (c == -1) { + perror("ioctl(SIOCLOOKUPSTAT)"); + return -1; + } + printf("Hash Tables:\t%lu\n", htstat.iphs_numtables); + printf("Nodes:\t%lu\n", htstat.iphs_numnodes); + printf("Out of Memory:\t%lu\n", htstat.iphs_nomem); + } + } + return 0; +} + + +int poolflush(argc, argv) +int argc; +char *argv[]; +{ + int c, role, type, arg; + iplookupflush_t flush; + + arg = IPLT_ALL; + type = IPLT_ALL; + role = IPL_LOGALL; + + while ((c = getopt(argc, argv, "do:t:v")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + break; + case 'o' : + role = getrole(optarg); + if (role == IPL_LOGNONE) { + fprintf(stderr, "unknown role '%s'\n", optarg); + return -1; + } + break; + case 't' : + type = gettype(optarg, NULL); + if (type == IPLT_NONE) { + fprintf(stderr, "unknown type '%s'\n", optarg); + return -1; + } + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (opts & OPT_DEBUG) + fprintf(stderr, "poolflush: opts = %#x\n", opts); + + if (!(opts & OPT_DONOTHING) && (fd == -1)) { + fd = open(IPLOOKUP_NAME, O_RDWR); + if (fd == -1) { + perror("open(IPLOOKUP_NAME)"); + exit(1); + } + } + + bzero((char *)&flush, sizeof(flush)); + flush.iplf_type = type; + flush.iplf_unit = role; + flush.iplf_arg = arg; + + if (!(opts & OPT_DONOTHING)) { + if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { + perror("ioctl(SIOCLOOKUPFLUSH)"); + exit(1); + } + + } + printf("%u object%s flushed\n", flush.iplf_count, + (flush.iplf_count == 1) ? "" : "s"); + + return 0; +} + + +int getrole(rolename) +char *rolename; +{ + int role; + + if (!strcasecmp(rolename, "ipf")) { + role = IPL_LOGIPF; +#if 0 + } else if (!strcasecmp(rolename, "nat")) { + role = IPL_LOGNAT; + } else if (!strcasecmp(rolename, "state")) { + role = IPL_LOGSTATE; + } else if (!strcasecmp(rolename, "auth")) { + role = IPL_LOGAUTH; + } else if (!strcasecmp(rolename, "sync")) { + role = IPL_LOGSYNC; + } else if (!strcasecmp(rolename, "scan")) { + role = IPL_LOGSCAN; + } else if (!strcasecmp(rolename, "pool")) { + role = IPL_LOGLOOKUP; + } else if (!strcasecmp(rolename, "count")) { + role = IPL_LOGCOUNT; +#endif + } else { + role = IPL_LOGNONE; + } + + return role; +} + + +int gettype(typename, minor) +char *typename; +u_int *minor; +{ + int type; + + if (!strcasecmp(optarg, "tree")) { + type = IPLT_POOL; + } else if (!strcasecmp(optarg, "hash")) { + type = IPLT_HASH; + if (minor != NULL) + *minor = IPHASH_LOOKUP; + } else if (!strcasecmp(optarg, "group-map")) { + type = IPLT_HASH; + if (minor != NULL) + *minor = IPHASH_GROUPMAP; + } else { + type = IPLT_NONE; + } + return type; +} diff --git a/contrib/ipfilter/tools/ippool_y.y b/contrib/ipfilter/tools/ippool_y.y new file mode 100644 index 000000000000..357745d0f0ca --- /dev/null +++ b/contrib/ipfilter/tools/ippool_y.y @@ -0,0 +1,415 @@ +/* $NetBSD$ */ + +%{ +#include +#include +#include +#include +#if defined(BSD) && (BSD >= 199306) +# include +#endif +#include + +#include +#if __FreeBSD_version >= 300000 +# include +#endif +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ipf.h" +#include "netinet/ip_lookup.h" +#include "netinet/ip_pool.h" +#include "netinet/ip_htable.h" +#include "ippool_l.h" +#include "kmem.h" + +#define YYDEBUG 1 + +extern int yyparse __P((void)); +extern int yydebug; +extern FILE *yyin; + +static iphtable_t ipht; +static iphtent_t iphte; +static ip_pool_t iplo; +static ioctlfunc_t poolioctl = NULL; +static char poolname[FR_GROUPLEN]; + +%} + +%union { + char *str; + u_32_t num; + struct in_addr addr; + struct alist_s *alist; + struct in_addr adrmsk[2]; + iphtent_t *ipe; + ip_pool_node_t *ipp; + union i6addr ip6; +} + +%token YY_NUMBER YY_HEX +%token YY_STR +%token YY_COMMENT +%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT +%token YY_RANGE_OUT YY_RANGE_IN +%token YY_IPV6 + +%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT +%token IPT_TABLE IPT_GROUPMAP IPT_HASH +%token IPT_ROLE IPT_TYPE IPT_TREE +%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME +%type role table inout +%type ipftree range addrlist +%type addrmask +%type ipfgroup ipfhash hashlist hashentry +%type groupentry setgrouplist grouplist +%type ipaddr mask ipv4 +%type number setgroup + +%% +file: line + | assign + | file line + | file assign + ; + +line: table role ipftree eol { iplo.ipo_unit = $2; + iplo.ipo_list = $3; + load_pool(&iplo, poolioctl); + resetlexer(); + } + | table role ipfhash eol { ipht.iph_unit = $2; + ipht.iph_type = IPHASH_LOOKUP; + load_hash(&ipht, $3, poolioctl); + resetlexer(); + } + | groupmap role number ipfgroup eol + { ipht.iph_unit = $2; + strncpy(ipht.iph_name, $3, + sizeof(ipht.iph_name)); + ipht.iph_type = IPHASH_GROUPMAP; + load_hash(&ipht, $4, poolioctl); + resetlexer(); + } + | YY_COMMENT + ; + +eol: ';' + ; + +assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); + resetlexer(); + free($1); + free($3); + } + ; + +assigning: + '=' { yyvarnext = 1; } + ; + +table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); + bzero((char *)&iphte, sizeof(iphte)); + bzero((char *)&iplo, sizeof(iplo)); + *ipht.iph_name = '\0'; + iplo.ipo_flags = IPHASH_ANON; + iplo.ipo_name[0] = '\0'; + } + ; + +groupmap: + IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); + bzero((char *)&iphte, sizeof(iphte)); + *ipht.iph_name = '\0'; + ipht.iph_unit = IPHASH_GROUPMAP; + ipht.iph_flags = $2; + } + ; + +inout: IPT_IN { $$ = FR_INQUE; } + | IPT_OUT { $$ = FR_OUTQUE; } + ; +role: + IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; } + | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; } + | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; } + | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; } + ; + +ipftree: + IPT_TYPE '=' IPT_TREE number start addrlist end + { strncpy(iplo.ipo_name, $4, + sizeof(iplo.ipo_name)); + $$ = $6; + } + ; + +ipfhash: + IPT_TYPE '=' IPT_HASH number hashopts start hashlist end + { strncpy(ipht.iph_name, $4, + sizeof(ipht.iph_name)); + $$ = $7; + } + ; + +ipfgroup: + setgroup hashopts start grouplist end + { iphtent_t *e; + for (e = $4; e != NULL; + e = e->ipe_next) + if (e->ipe_group[0] == '\0') + strncpy(e->ipe_group, + $1, + FR_GROUPLEN); + $$ = $4; + } + | hashopts start setgrouplist end { $$ = $3; } + ; + +number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); + $$ = poolname; + } + | IPT_NAME '=' YY_STR { $$ = $3; } + | { $$ = ""; } + ; + +setgroup: + IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; + strncpy(tmp, $3, FR_GROUPLEN); + $$ = strdup(tmp); + } + | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; + sprintf(tmp, "%u", $3); + $$ = strdup(tmp); + } + ; + +hashopts: + | size + | seed + | size seed + ; + +addrlist: + next { $$ = NULL; } + | range next addrlist { $1->ipn_next = $3; $$ = $1; } + | range next { $$ = $1; } + ; + +grouplist: + next { $$ = NULL; } + | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } + | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); + bcopy((char *)&($1[0]), + (char *)&($$->ipe_addr), + sizeof($$->ipe_addr)); + bcopy((char *)&($1[1]), + (char *)&($$->ipe_mask), + sizeof($$->ipe_mask)); + $$->ipe_next = $3; + } + | groupentry next { $$ = $1; } + | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); + bcopy((char *)&($1[0]), + (char *)&($$->ipe_addr), + sizeof($$->ipe_addr)); + bcopy((char *)&($1[1]), + (char *)&($$->ipe_mask), + sizeof($$->ipe_mask)); + } + ; + +setgrouplist: + next { $$ = NULL; } + | groupentry next { $$ = $1; } + | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } + ; + +groupentry: + addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); + bcopy((char *)&($1[0]), + (char *)&($$->ipe_addr), + sizeof($$->ipe_addr)); + bcopy((char *)&($1[1]), + (char *)&($$->ipe_mask), + sizeof($$->ipe_mask)); + strncpy($$->ipe_group, $3, + FR_GROUPLEN); + free($3); + } + ; + +range: addrmask { $$ = calloc(1, sizeof(*$$)); + $$->ipn_info = 0; + $$->ipn_addr.adf_len = sizeof($$->ipn_addr); + $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr; + $$->ipn_mask.adf_len = sizeof($$->ipn_mask); + $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr; + } + | '!' addrmask { $$ = calloc(1, sizeof(*$$)); + $$->ipn_info = 1; + $$->ipn_addr.adf_len = sizeof($$->ipn_addr); + $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr; + $$->ipn_mask.adf_len = sizeof($$->ipn_mask); + $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr; + } + +hashlist: + next { $$ = NULL; } + | hashentry next { $$ = $1; } + | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } + ; + +hashentry: + addrmask { $$ = calloc(1, sizeof(iphtent_t)); + bcopy((char *)&($1[0]), + (char *)&($$->ipe_addr), + sizeof($$->ipe_addr)); + bcopy((char *)&($1[1]), + (char *)&($$->ipe_mask), + sizeof($$->ipe_mask)); + } + ; + +addrmask: + ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr; + yyexpectaddr = 0; + } + | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff; + yyexpectaddr = 0; + } + ; + +ipaddr: ipv4 { $$ = $1; } + | YY_NUMBER { $$.s_addr = htonl($1); } + | YY_STR { if (gethost($1, &($$.s_addr)) == -1) + yyerror("Unknown hostname"); + } + ; + +mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); } + | ipv4 { $$ = $1; } + ; + +start: '{' { yyexpectaddr = 1; } + ; + +end: '}' { yyexpectaddr = 0; } + ; + +next: ';' { yyexpectaddr = 1; } + ; + +size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } + ; + +seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } + ; + +ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER + { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { + yyerror("Invalid octet string for IP address"); + return 0; + } + $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; + $$.s_addr = htonl($$.s_addr); + } + ; +%% +static wordtab_t yywords[] = { + { "auth", IPT_AUTH }, + { "count", IPT_COUNT }, + { "group", IPT_GROUP }, + { "group-map", IPT_GROUPMAP }, + { "hash", IPT_HASH }, + { "in", IPT_IN }, + { "ipf", IPT_IPF }, + { "name", IPT_NAME }, + { "nat", IPT_NAT }, + { "number", IPT_NUM }, + { "out", IPT_OUT }, + { "role", IPT_ROLE }, + { "seed", IPT_SEED }, + { "size", IPT_SIZE }, + { "table", IPT_TABLE }, + { "tree", IPT_TREE }, + { "type", IPT_TYPE }, + { NULL, 0 } +}; + + +int ippool_parsefile(fd, filename, iocfunc) +int fd; +char *filename; +ioctlfunc_t iocfunc; +{ + FILE *fp = NULL; + char *s; + + yylineNum = 1; + (void) yysettab(yywords); + + s = getenv("YYDEBUG"); + if (s) + yydebug = atoi(s); + else + yydebug = 0; + + if (strcmp(filename, "-")) { + fp = fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "fopen(%s) failed: %s\n", filename, + STRERROR(errno)); + return -1; + } + } else + fp = stdin; + + while (ippool_parsesome(fd, fp, iocfunc) == 1) + ; + if (fp != NULL) + fclose(fp); + return 0; +} + + +int ippool_parsesome(fd, fp, iocfunc) +int fd; +FILE *fp; +ioctlfunc_t iocfunc; +{ + char *s; + int i; + + poolioctl = iocfunc; + + if (feof(fp)) + return 0; + i = fgetc(fp); + if (i == EOF) + return 0; + if (ungetc(i, fp) == EOF) + return 0; + if (feof(fp)) + return 0; + s = getenv("YYDEBUG"); + if (s) + yydebug = atoi(s); + else + yydebug = 0; + + yyin = fp; + yyparse(); + return 1; +} diff --git a/contrib/ipfilter/tools/ipscan_y.y b/contrib/ipfilter/tools/ipscan_y.y new file mode 100644 index 000000000000..64cbb6d0125d --- /dev/null +++ b/contrib/ipfilter/tools/ipscan_y.y @@ -0,0 +1,565 @@ +/* $NetBSD$ */ + +%{ +#include +#include +#include "ipf.h" +#include "opts.h" +#include "kmem.h" +#include "ipscan_l.h" +#include "netinet/ip_scan.h" + +#define YYDEBUG 1 + +extern char *optarg; +extern void yyerror __P((char *)); +extern int yyparse __P((void)); +extern int yylex __P((void)); +extern int yydebug; +extern FILE *yyin; +extern int yylineNum; +extern void printbuf __P((char *, int, int)); + + +void printent __P((ipscan_t *)); +void showlist __P((void)); +int getportnum __P((char *)); +struct in_addr gethostip __P((char *)); +struct in_addr combine __P((int, int, int, int)); +char **makepair __P((char *, char *)); +void addtag __P((char *, char **, char **, struct action *)); +int cram __P((char *, char *)); +void usage __P((char *)); +int main __P((int, char **)); + +int opts = 0; +int fd = -1; + + +%} + +%union { + char *str; + char **astr; + u_32_t num; + struct in_addr ipa; + struct action act; + union i6addr ip6; +} + +%type tag +%type action redirect result +%type ipaddr +%type portnum +%type matchup onehalf twohalves + +%token YY_NUMBER YY_HEX +%token YY_STR +%token YY_COMMENT +%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT +%token YY_RANGE_OUT YY_RANGE_IN +%token YY_IPV6 +%token IPSL_START IPSL_STARTGROUP IPSL_CONTENT + +%token IPSL_CLOSE IPSL_TRACK IPSL_EOF IPSL_REDIRECT IPSL_ELSE + +%% +file: line ';' + | assign ';' + | file line ';' + | file assign ';' + | YY_COMMENT + ; + +line: IPSL_START dline + | IPSL_STARTGROUP gline + | IPSL_CONTENT oline + ; + +dline: cline { resetlexer(); } + | sline { resetlexer(); } + | csline { resetlexer(); } + ; + +gline: YY_STR ':' glist '=' action + ; + +oline: cline + | sline + | csline + ; + +assign: YY_STR assigning YY_STR + { set_variable($1, $3); + resetlexer(); + free($1); + free($3); + } + ; + +assigning: + '=' { yyvarnext = 1; } + ; + +cline: tag ':' matchup '=' action { addtag($1, $3, NULL, &$5); } + ; + +sline: tag ':' '(' ')' ',' matchup '=' action { addtag($1, NULL, $6, &$8); } + ; + +csline: tag ':' matchup ',' matchup '=' action { addtag($1, $3, $5, &$7); } + ; + +glist: YY_STR + | glist ',' YY_STR + ; + +tag: YY_STR { $$ = $1; } + ; + +matchup: + onehalf { $$ = $1; } + | twohalves { $$ = $1; } + ; + +action: result { $$.act_val = $1.act_val; + $$.act_ip = $1.act_ip; + $$.act_port = $1.act_port; } + | result IPSL_ELSE result { $$.act_val = $1.act_val; + $$.act_else = $3.act_val; + if ($1.act_val == IPSL_REDIRECT) { + $$.act_ip = $1.act_ip; + $$.act_port = $1.act_port; + } + if ($3.act_val == IPSL_REDIRECT) { + $$.act_eip = $3.act_eip; + $$.act_eport = $3.act_eport; + } + } + +result: IPSL_CLOSE { $$.act_val = IPSL_CLOSE; } + | IPSL_TRACK { $$.act_val = IPSL_TRACK; } + | redirect { $$.act_val = IPSL_REDIRECT; + $$.act_ip = $1.act_ip; + $$.act_port = $1.act_port; } + ; + +onehalf: + '(' YY_STR ')' { $$ = makepair($2, NULL); } + ; + +twohalves: + '(' YY_STR ',' YY_STR ')' { $$ = makepair($2, $4); } + ; + +redirect: + IPSL_REDIRECT '(' ipaddr ')' { $$.act_ip = $3; + $$.act_port = 0; } + | IPSL_REDIRECT '(' ipaddr ',' portnum ')' + { $$.act_ip = $3; + $$.act_port = $5; } + ; + + +ipaddr: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER + { $$ = combine($1,$3,$5,$7); } + | YY_STR { $$ = gethostip($1); + free($1); + } + ; + +portnum: + YY_NUMBER { $$ = htons($1); } + | YY_STR { $$ = getportnum($1); + free($1); + } + ; + +%% + + +static struct wordtab yywords[] = { + { "close", IPSL_CLOSE }, + { "content", IPSL_CONTENT }, + { "else", IPSL_ELSE }, + { "start-group", IPSL_STARTGROUP }, + { "redirect", IPSL_REDIRECT }, + { "start", IPSL_START }, + { "track", IPSL_TRACK }, + { NULL, 0 } +}; + + +int cram(dst, src) +char *dst; +char *src; +{ + char c, *s, *t, *u; + int i, j, k; + + c = *src; + s = src + 1; + t = strchr(s, c); + *t = '\0'; + for (u = dst, i = 0; (i <= ISC_TLEN) && (s < t); ) { + c = *s++; + if (c == '\\') { + if (s >= t) + break; + j = k = 0; + do { + c = *s++; + if (j && (!ISDIGIT(c) || (c > '7') || + (k >= 248))) { + *u++ = k, i++; + j = k = 0; + s--; + break; + } + i++; + + if (ISALPHA(c) || (c > '7')) { + switch (c) + { + case 'n' : + *u++ = '\n'; + break; + case 'r' : + *u++ = '\r'; + break; + case 't' : + *u++ = '\t'; + break; + default : + *u++ = c; + break; + } + } else if (ISDIGIT(c)) { + j = 1; + k <<= 3; + k |= (c - '0'); + i--; + } else + *u++ = c; + } while ((i <= ISC_TLEN) && (s <= t) && (j > 0)); + } else + *u++ = c, i++; + } + return i; +} + + +void printent(isc) +ipscan_t *isc; +{ + char buf[ISC_TLEN+1]; + u_char *u; + int i, j; + + buf[ISC_TLEN] = '\0'; + bcopy(isc->ipsc_ctxt, buf, ISC_TLEN); + printf("%s : (\"", isc->ipsc_tag); + printbuf(isc->ipsc_ctxt, isc->ipsc_clen, 0); + + bcopy(isc->ipsc_cmsk, buf, ISC_TLEN); + printf("\", \"%s\"), (\"", buf); + + printbuf(isc->ipsc_stxt, isc->ipsc_slen, 0); + + bcopy(isc->ipsc_smsk, buf, ISC_TLEN); + printf("\", \"%s\") = ", buf); + + switch (isc->ipsc_action) + { + case ISC_A_TRACK : + printf("track"); + break; + case ISC_A_REDIRECT : + printf("redirect"); + printf("(%s", inet_ntoa(isc->ipsc_ip)); + if (isc->ipsc_port) + printf(",%d", isc->ipsc_port); + printf(")"); + break; + case ISC_A_CLOSE : + printf("close"); + break; + default : + break; + } + + if (isc->ipsc_else != ISC_A_NONE) { + printf(" else "); + switch (isc->ipsc_else) + { + case ISC_A_TRACK : + printf("track"); + break; + case ISC_A_REDIRECT : + printf("redirect"); + printf("(%s", inet_ntoa(isc->ipsc_eip)); + if (isc->ipsc_eport) + printf(",%d", isc->ipsc_eport); + printf(")"); + break; + case ISC_A_CLOSE : + printf("close"); + break; + default : + break; + } + } + printf("\n"); + + if (opts & OPT_DEBUG) { + for (u = (u_char *)isc, i = sizeof(*isc); i; ) { + printf("#"); + for (j = 32; (j > 0) && (i > 0); j--, i--) + printf("%s%02x", (j & 7) ? "" : " ", *u++); + printf("\n"); + } + } + if (opts & OPT_VERBOSE) { + printf("# hits %d active %d fref %d sref %d\n", + isc->ipsc_hits, isc->ipsc_active, isc->ipsc_fref, + isc->ipsc_sref); + } +} + + +void addtag(tstr, cp, sp, act) +char *tstr; +char **cp, **sp; +struct action *act; +{ + ipscan_t isc, *iscp; + + bzero((char *)&isc, sizeof(isc)); + + strncpy(isc.ipsc_tag, tstr, sizeof(isc.ipsc_tag)); + isc.ipsc_tag[sizeof(isc.ipsc_tag) - 1] = '\0'; + + if (cp) { + isc.ipsc_clen = cram(isc.ipsc_ctxt, cp[0]); + if (cp[1]) { + if (cram(isc.ipsc_cmsk, cp[1]) != isc.ipsc_clen) { + fprintf(stderr, + "client text/mask strings different length\n"); + return; + } + } + } + + if (sp) { + isc.ipsc_slen = cram(isc.ipsc_stxt, sp[0]); + if (sp[1]) { + if (cram(isc.ipsc_smsk, sp[1]) != isc.ipsc_slen) { + fprintf(stderr, + "server text/mask strings different length\n"); + return; + } + } + } + + if (act->act_val == IPSL_CLOSE) { + isc.ipsc_action = ISC_A_CLOSE; + } else if (act->act_val == IPSL_TRACK) { + isc.ipsc_action = ISC_A_TRACK; + } else if (act->act_val == IPSL_REDIRECT) { + isc.ipsc_action = ISC_A_REDIRECT; + isc.ipsc_ip = act->act_ip; + isc.ipsc_port = act->act_port; + fprintf(stderr, "%d: redirect unsupported\n", yylineNum + 1); + } + + if (act->act_else == IPSL_CLOSE) { + isc.ipsc_else = ISC_A_CLOSE; + } else if (act->act_else == IPSL_TRACK) { + isc.ipsc_else = ISC_A_TRACK; + } else if (act->act_else == IPSL_REDIRECT) { + isc.ipsc_else = ISC_A_REDIRECT; + isc.ipsc_eip = act->act_eip; + isc.ipsc_eport = act->act_eport; + fprintf(stderr, "%d: redirect unsupported\n", yylineNum + 1); + } + + if (!(opts & OPT_DONOTHING)) { + iscp = &isc; + if (opts & OPT_REMOVE) { + if (ioctl(fd, SIOCRMSCA, &iscp) == -1) + perror("SIOCADSCA"); + } else { + if (ioctl(fd, SIOCADSCA, &iscp) == -1) + perror("SIOCADSCA"); + } + } + + if (opts & OPT_VERBOSE) + printent(&isc); +} + + +char **makepair(s1, s2) +char *s1, *s2; +{ + char **a; + + a = malloc(sizeof(char *) * 2); + a[0] = s1; + a[1] = s2; + return a; +} + + +struct in_addr combine(a1, a2, a3, a4) +int a1, a2, a3, a4; +{ + struct in_addr in; + + a1 &= 0xff; + in.s_addr = a1 << 24; + a2 &= 0xff; + in.s_addr |= (a2 << 16); + a3 &= 0xff; + in.s_addr |= (a3 << 8); + a4 &= 0xff; + in.s_addr |= a4; + in.s_addr = htonl(in.s_addr); + return in; +} + + +struct in_addr gethostip(host) +char *host; +{ + struct hostent *hp; + struct in_addr in; + + in.s_addr = 0; + + hp = gethostbyname(host); + if (!hp) + return in; + bcopy(hp->h_addr, (char *)&in, sizeof(in)); + return in; +} + + +int getportnum(port) +char *port; +{ + struct servent *s; + + s = getservbyname(port, "tcp"); + if (s == NULL) + return -1; + return s->s_port; +} + + +void showlist() +{ + ipscanstat_t ipsc, *ipscp = &ipsc; + ipscan_t isc; + + if (ioctl(fd, SIOCGSCST, &ipscp) == -1) + perror("ioctl(SIOCGSCST)"); + else if (opts & OPT_SHOWLIST) { + while (ipsc.iscs_list != NULL) { + if (kmemcpy((char *)&isc, (u_long)ipsc.iscs_list, + sizeof(isc)) == -1) { + perror("kmemcpy"); + break; + } else { + printent(&isc); + ipsc.iscs_list = isc.ipsc_next; + } + } + } else { + printf("scan entries loaded\t%d\n", ipsc.iscs_entries); + printf("scan entries matches\t%ld\n", ipsc.iscs_acted); + printf("negative matches\t%ld\n", ipsc.iscs_else); + } +} + + +void usage(prog) +char *prog; +{ + fprintf(stderr, "Usage:\t%s [-dnrv] -f \n", prog); + fprintf(stderr, "\t%s [-dlv]\n", prog); + exit(1); +} + + +int main(argc, argv) +int argc; +char *argv[]; +{ + FILE *fp = NULL; + int c; + + (void) yysettab(yywords); + + if (argc < 2) + usage(argv[0]); + + while ((c = getopt(argc, argv, "df:lnrsv")) != -1) + switch (c) + { + case 'd' : + opts |= OPT_DEBUG; + yydebug++; + break; + case 'f' : + if (!strcmp(optarg, "-")) + fp = stdin; + else { + fp = fopen(optarg, "r"); + if (!fp) { + perror("open"); + exit(1); + } + } + yyin = fp; + break; + case 'l' : + opts |= OPT_SHOWLIST; + break; + case 'n' : + opts |= OPT_DONOTHING; + break; + case 'r' : + opts |= OPT_REMOVE; + break; + case 's' : + opts |= OPT_STAT; + break; + case 'v' : + opts |= OPT_VERBOSE; + break; + } + + if (!(opts & OPT_DONOTHING)) { + fd = open(IPL_SCAN, O_RDWR); + if (fd == -1) { + perror("open(IPL_SCAN)"); + exit(1); + } + } + + if (fp != NULL) { + yylineNum = 1; + + while (!feof(fp)) + yyparse(); + fclose(fp); + exit(0); + } + + if (opts & (OPT_SHOWLIST|OPT_STAT)) { + showlist(); + exit(0); + } + exit(1); +} diff --git a/contrib/ipfilter/tools/ipsyncm.c b/contrib/ipfilter/tools/ipsyncm.c new file mode 100644 index 000000000000..20cc25e9d685 --- /dev/null +++ b/contrib/ipfilter/tools/ipsyncm.c @@ -0,0 +1,253 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipsyncm.c,v 1.4.2.2 2005/01/08 14:31:46 darrenr Exp"; +#endif +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_state.h" +#include "netinet/ip_sync.h" + + +int main __P((int, char *[])); + +int terminate = 0; + +void usage(const char *progname) { + fprintf(stderr, "Usage: %s \n", progname); +} + +static void handleterm(int sig) +{ + terminate = sig; +} + + +/* should be large enough to hold header + any datatype */ +#define BUFFERLEN 1400 + +int main(argc, argv) +int argc; +char *argv[]; +{ + struct sockaddr_in sin; + char buff[BUFFERLEN]; + synclogent_t *sl; + syncupdent_t *su; + int nfd = -1, lfd = -1, n1, n2, n3, len; + int inbuf; + u_32_t magic; + synchdr_t *sh; + char *progname; + + progname = strrchr(argv[0], '/'); + if (progname) { + progname++; + } else { + progname = argv[0]; + } + + + if (argc < 2) { + usage(progname); + exit(1); + } + +#if 0 + signal(SIGHUP, handleterm); + signal(SIGINT, handleterm); + signal(SIGTERM, handleterm); +#endif + + openlog(progname, LOG_PID, LOG_SECURITY); + + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(argv[1]); + if (argc > 2) + sin.sin_port = htons(atoi(argv[2])); + else + sin.sin_port = htons(43434); + + while (1) { + + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + lfd = open(IPSYNC_NAME, O_RDONLY); + if (lfd == -1) { + syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); + goto tryagain; + } + + nfd = socket(AF_INET, SOCK_DGRAM, 0); + if (nfd == -1) { + syslog(LOG_ERR, "Socket :%m"); + goto tryagain; + } + + if (connect(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + syslog(LOG_ERR, "Connect: %m"); + goto tryagain; + } + + syslog(LOG_INFO, "Established connection to %s", + inet_ntoa(sin.sin_addr)); + + inbuf = 0; + while (1) { + + n1 = read(lfd, buff+inbuf, BUFFERLEN-inbuf); + + printf("header : %d bytes read (header = %d bytes)\n", + n1, sizeof(*sh)); + + if (n1 < 0) { + syslog(LOG_ERR, "Read error (header): %m"); + goto tryagain; + } + + if (n1 == 0) { + /* XXX can this happen??? */ + syslog(LOG_ERR, + "Read error (header) : No data"); + sleep(1); + continue; + } + + inbuf += n1; + +moreinbuf: + if (inbuf < sizeof(*sh)) { + continue; /* need more data */ + } + + sh = (synchdr_t *)buff; + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, + "Invalid header magic %x", magic); + goto tryagain; + } + +#define IPSYNC_DEBUG +#ifdef IPSYNC_DEBUG + printf("v:%d p:%d len:%d magic:%x", sh->sm_v, + sh->sm_p, len, magic); + + if (sh->sm_cmd == SMC_CREATE) + printf(" cmd:CREATE"); + else if (sh->sm_cmd == SMC_UPDATE) + printf(" cmd:UPDATE"); + else + printf(" cmd:Unknown(%d)", sh->sm_cmd); + + if (sh->sm_table == SMC_NAT) + printf(" table:NAT"); + else if (sh->sm_table == SMC_STATE) + printf(" table:STATE"); + else + printf(" table:Unknown(%d)", sh->sm_table); + + printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); +#endif + + if (inbuf < sizeof(*sh) + len) { + continue; /* need more data */ + goto tryagain; + } + +#ifdef IPSYNC_DEBUG + if (sh->sm_cmd == SMC_CREATE) { + sl = (synclogent_t *)buff; + + } else if (sh->sm_cmd == SMC_UPDATE) { + su = (syncupdent_t *)buff; + if (sh->sm_p == IPPROTO_TCP) { + printf(" TCP Update: age %lu state %d/%d\n", + su->sup_tcp.stu_age, + su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[1]); + } + } else { + printf("Unknown command\n"); + } +#endif + + n2 = sizeof(*sh) + len; + n3 = write(nfd, buff, n2); + if (n3 <= 0) { + syslog(LOG_ERR, "Write error: %m"); + goto tryagain; + } + + + if (n3 != n2) { + syslog(LOG_ERR, "Incomplete write (%d/%d)", + n3, n2); + goto tryagain; + } + + /* signal received? */ + if (terminate) + break; + + /* move buffer to the front,we might need to make + * this more efficient, by using a rolling pointer + * over the buffer and only copying it, when + * we are reaching the end + */ + inbuf -= n2; + if (inbuf) { + bcopy(buff+n2, buff, inbuf); + printf("More data in buffer\n"); + goto moreinbuf; + } + } + + if (terminate) + break; +tryagain: + sleep(1); + } + + + /* terminate */ + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + syslog(LOG_ERR, "signal %d received, exiting...", terminate); + + exit(1); +} + diff --git a/contrib/ipfilter/tools/ipsyncs.c b/contrib/ipfilter/tools/ipsyncs.c new file mode 100644 index 000000000000..a189a9bcad24 --- /dev/null +++ b/contrib/ipfilter/tools/ipsyncs.c @@ -0,0 +1,272 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 1993-2001 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#if !defined(lint) +static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; +static const char rcsid[] = "@(#)Id: ipsyncs.c,v 1.5.2.1 2004/10/31 18:46:44 darrenr Exp"; +#endif +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" +#include "netinet/ip_state.h" +#include "netinet/ip_nat.h" +#include "netinet/ip_sync.h" + +int main __P((int, char *[])); + +int terminate = 0; + +void usage(const char *progname) { + fprintf(stderr, + "Usage: %s [remote IP]\n", + progname); +} + +static void handleterm(int sig) +{ + terminate = sig; + +} + +#define BUFFERLEN 1400 + +int main(argc, argv) +int argc; +char *argv[]; +{ + int nfd = -1 , lfd = -1; + int n1, n2, n3, magic, len, inbuf; + struct sockaddr_in sin; + struct sockaddr_in in; + char buff[BUFFERLEN]; + synclogent_t *sl; + syncupdent_t *su; + synchdr_t *sh; + char *progname; + + progname = strrchr(argv[0], '/'); + if (progname) { + progname++; + } else { + progname = argv[0]; + } + + if (argc < 2) { + usage(progname); + exit(1); + } + +#if 0 + signal(SIGHUP, handleterm); + signal(SIGINT, handleterm); + signal(SIGTERM, handleterm); +#endif + + openlog(progname, LOG_PID, LOG_SECURITY); + + lfd = open(IPSYNC_NAME, O_WRONLY); + if (lfd == -1) { + syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); + exit(1); + } + + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + if (argc > 1) + sin.sin_addr.s_addr = inet_addr(argv[1]); + if (argc > 2) + sin.sin_port = htons(atoi(argv[2])); + else + sin.sin_port = htons(43434); + if (argc > 3) + in.sin_addr.s_addr = inet_addr(argv[3]); + else + in.sin_addr.s_addr = 0; + in.sin_port = 0; + + while(1) { + + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + lfd = open(IPSYNC_NAME, O_WRONLY); + if (lfd == -1) { + syslog(LOG_ERR, "Opening %s :%m", IPSYNC_NAME); + goto tryagain; + } + + nfd = socket(AF_INET, SOCK_DGRAM, 0); + if (nfd == -1) { + syslog(LOG_ERR, "Socket :%m"); + goto tryagain; + } + + n1 = 1; + setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &n1, sizeof(n1)); + + if (bind(nfd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + syslog(LOG_ERR, "Bind: %m"); + goto tryagain; + } + + syslog(LOG_INFO, "Established connection to %s", + inet_ntoa(sin.sin_addr)); + + inbuf = 0; + while (1) { + + + /* + * XXX currently we do not check the source address + * of a datagram, this can be a security risk + */ + n1 = read(nfd, buff+inbuf, BUFFERLEN-inbuf); + + printf("header : %d bytes read (header = %d bytes)\n", + n1, sizeof(*sh)); + + if (n1 < 0) { + syslog(LOG_ERR, "Read error (header): %m"); + goto tryagain; + } + + if (n1 == 0) { + /* XXX can this happen??? */ + syslog(LOG_ERR, + "Read error (header) : No data"); + sleep(1); + continue; + } + + inbuf += n1; + +moreinbuf: + if (inbuf < sizeof(*sh)) { + continue; /* need more data */ + } + + sh = (synchdr_t *)buff; + len = ntohl(sh->sm_len); + magic = ntohl(sh->sm_magic); + + if (magic != SYNHDRMAGIC) { + syslog(LOG_ERR, "Invalid header magic %x", + magic); + goto tryagain; + } + +#define IPSYNC_DEBUG +#ifdef IPSYNC_DEBUG + printf("v:%d p:%d len:%d magic:%x", sh->sm_v, + sh->sm_p, len, magic); + + if (sh->sm_cmd == SMC_CREATE) + printf(" cmd:CREATE"); + else if (sh->sm_cmd == SMC_UPDATE) + printf(" cmd:UPDATE"); + else + printf(" cmd:Unknown(%d)", sh->sm_cmd); + + if (sh->sm_table == SMC_NAT) + printf(" table:NAT"); + else if (sh->sm_table == SMC_STATE) + printf(" table:STATE"); + else + printf(" table:Unknown(%d)", sh->sm_table); + + printf(" num:%d\n", (u_32_t)ntohl(sh->sm_num)); +#endif + + if (inbuf < sizeof(*sh) + len) { + continue; /* need more data */ + goto tryagain; + } + +#ifdef IPSYNC_DEBUG + if (sh->sm_cmd == SMC_CREATE) { + sl = (synclogent_t *)buff; + + } else if (sh->sm_cmd == SMC_UPDATE) { + su = (syncupdent_t *)buff; + if (sh->sm_p == IPPROTO_TCP) { + printf(" TCP Update: age %lu state %d/%d\n", + su->sup_tcp.stu_age, + su->sup_tcp.stu_state[0], + su->sup_tcp.stu_state[1]); + } + } else { + printf("Unknown command\n"); + } +#endif + + n2 = sizeof(*sh) + len; + n3 = write(lfd, buff, n2); + if (n3 <= 0) { + syslog(LOG_ERR, "Write error: %m"); + goto tryagain; + } + + + if (n3 != n2) { + syslog(LOG_ERR, "Incomplete write (%d/%d)", + n3, n2); + goto tryagain; + } + + /* signal received? */ + if (terminate) + break; + + /* move buffer to the front,we might need to make + * this more efficient, by using a rolling pointer + * over the buffer and only copying it, when + * we are reaching the end + */ + inbuf -= n2; + if (inbuf) { + bcopy(buff+n2, buff, inbuf); + printf("More data in buffer\n"); + goto moreinbuf; + } + } + + if (terminate) + break; +tryagain: + sleep(1); + } + + + /* terminate */ + if (lfd != -1) + close(lfd); + if (nfd != -1) + close(nfd); + + syslog(LOG_ERR, "signal %d received, exiting...", terminate); + + exit(1); +} diff --git a/contrib/ipfilter/tools/lex_var.h b/contrib/ipfilter/tools/lex_var.h new file mode 100644 index 000000000000..33fba256b973 --- /dev/null +++ b/contrib/ipfilter/tools/lex_var.h @@ -0,0 +1,55 @@ +/* $NetBSD$ */ + + +extern long string_start; +extern long string_end; +extern char *string_val; +extern long pos; + +#define YY_INPUT(buf, result, max_size) \ + if (pos >= string_start && pos <= string_end) { \ + buf[0] = string_val[pos - string_start]; \ + pos++; \ + result = 1; \ + } else if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < 1 && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + pos++; \ + } \ + else if ( ((result = fread( buf, 1, 1, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); + +#ifdef input +# undef input +# define input() (((pos >= string_start) && (pos < string_end)) ? \ + yysptr = yysbuf, string_val[pos++ - string_start] : \ + ((yytchar = yysptr > yysbuf ? U(*--yysptr) : \ + getc(yyin)) == 10 ? (pos++, yylineno++, yytchar) : \ + yytchar) == EOF ? (pos++, 0) : (pos++, yytchar)) +#endif + +#ifdef lex_input +# undef lex_input +# define lex_input() (((pos >= string_start) && (pos < string_end)) ? \ + yysptr = yysbuf, string_val[pos++ - string_start] : \ + ((yytchar = yysptr > yysbuf ? U(*--yysptr) : \ + getc(yyin)) == 10 ? (pos++, yylineno++, yytchar) : \ + yytchar) == EOF ? (pos++, 0) : (pos++, yytchar)) +#endif + +#ifdef unput +# undef unput +# define unput(c) { if (pos > 0) pos--; \ + yytchar = (c); if (yytchar == '\n') yylineno--; \ + *yysptr++ = yytchar; } +#endif + diff --git a/contrib/ipfilter/tools/lexer.c b/contrib/ipfilter/tools/lexer.c new file mode 100644 index 000000000000..f6fccfbbc624 --- /dev/null +++ b/contrib/ipfilter/tools/lexer.c @@ -0,0 +1,632 @@ +/* $NetBSD$ */ + +/* + * Copyright (C) 2003 by Darren Reed. + * + * See the IPFILTER.LICENCE file for details on licencing. + */ +#include +#include "ipf.h" +#ifdef IPFILTER_SCAN +# include "netinet/ip_scan.h" +#endif +#include +#include +#ifdef TEST_LEXER +# define NO_YACC +union { + int num; + char *str; + struct in_addr ipa; + i6addr_t ip6; +} yylval; +#endif +#include "lexer.h" +#include "y.tab.h" + +FILE *yyin; + +#define ishex(c) (ISDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || \ + ((c) >= 'A' && (c) <= 'F')) +#define TOOLONG -3 + +extern int string_start; +extern int string_end; +extern char *string_val; +extern int pos; +extern int yydebug; + +char *yystr = NULL; +int yytext[YYBUFSIZ+1]; +int yylineNum = 1; +int yypos = 0; +int yylast = -1; +int yyexpectaddr = 0; +int yybreakondot = 0; +int yyvarnext = 0; +int yytokentype = 0; +wordtab_t *yywordtab = NULL; +int yysavedepth = 0; +wordtab_t *yysavewords[30]; + + +static wordtab_t *yyfindkey __P((char *)); +static int yygetc __P((void)); +static void yyunputc __P((int)); +static int yyswallow __P((int)); +static char *yytexttostr __P((int, int)); +static void yystrtotext __P((char *)); + +static int yygetc() +{ + int c; + + if (yypos < yylast) { + c = yytext[yypos++]; + if (c == '\n') + yylineNum++; + return c; + } + + if (yypos == YYBUFSIZ) + return TOOLONG; + + if (pos >= string_start && pos <= string_end) { + c = string_val[pos - string_start]; + yypos++; + } else { + c = fgetc(yyin); + } + if (c == '\n') + yylineNum++; + yytext[yypos++] = c; + yylast = yypos; + yytext[yypos] = '\0'; + + return c; +} + + +static void yyunputc(c) +int c; +{ + if (c == '\n') + yylineNum--; + yytext[--yypos] = c; +} + + +static int yyswallow(last) +int last; +{ + int c; + + while (((c = yygetc()) > '\0') && (c != last)) + ; + + if (c != EOF) + yyunputc(c); + if (c == last) + return 0; + return -1; +} + + +static void yystrtotext(str) +char *str; +{ + int len; + char *s; + + len = strlen(str); + if (len > YYBUFSIZ) + len = YYBUFSIZ; + + for (s = str; *s != '\0' && len > 0; s++, len--) + yytext[yylast++] = *s; + yytext[yylast] = '\0'; +} + + +static char *yytexttostr(offset, max) +int offset, max; +{ + char *str; + int i; + + if ((yytext[offset] == '\'' || yytext[offset] == '"') && + (yytext[offset] == yytext[offset + max - 1])) { + offset++; + max--; + } + + if (max > yylast) + max = yylast; + str = malloc(max + 1); + if (str != NULL) { + for (i = offset; i < max; i++) + str[i - offset] = (char)(yytext[i] & 0xff); + str[i - offset] = '\0'; + } + return str; +} + + +int yylex() +{ + int c, n, isbuilding, rval, lnext, nokey = 0; + char *name; + + isbuilding = 0; + lnext = 0; + rval = 0; + + if (yystr != NULL) { + free(yystr); + yystr = NULL; + } + +nextchar: + c = yygetc(); + + switch (c) + { + case '\n' : + case '\t' : + case '\r' : + case ' ' : + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + if (yylast > yypos) { + bcopy(yytext + yypos, yytext, + sizeof(yytext[0]) * (yylast - yypos + 1)); + } + yylast -= yypos; + yypos = 0; + lnext = 0; + nokey = 0; + goto nextchar; + + case '\\' : + if (lnext == 0) { + lnext = 1; + if (yylast == yypos) { + yylast--; + yypos--; + } else + yypos--; + if (yypos == 0) + nokey = 1; + goto nextchar; + } + break; + } + + if (lnext == 1) { + lnext = 0; + if ((isbuilding == 0) && !ISALNUM(c)) { + return c; + } + goto nextchar; + } + + switch (c) + { + case '#' : + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + yyswallow('\n'); + rval = YY_COMMENT; + goto nextchar; + + case '$' : + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + n = yygetc(); + if (n == '{') { + if (yyswallow('}') == -1) { + rval = -2; + goto done; + } + (void) yygetc(); + } else { + if (!ISALPHA(n)) { + yyunputc(n); + break; + } + do { + n = yygetc(); + } while (ISALPHA(n) || ISDIGIT(n) || n == '_'); + yyunputc(n); + } + + name = yytexttostr(1, yypos); /* skip $ */ + + if (name != NULL) { + string_val = get_variable(name, NULL, yylineNum); + free(name); + if (string_val != NULL) { + name = yytexttostr(yypos, yylast); + if (name != NULL) { + yypos = 0; + yylast = 0; + yystrtotext(string_val); + yystrtotext(name); + free(string_val); + free(name); + goto nextchar; + } + free(string_val); + } + } + break; + + case '\'': + case '"' : + if (isbuilding == 1) { + goto done; + } + do { + n = yygetc(); + if (n == EOF || n == TOOLONG) { + rval = -2; + goto done; + } + if (n == '\n') { + yyunputc(' '); + yypos++; + } + } while (n != c); + yyunputc(n); + break; + + case EOF : + yylineNum = 1; + yypos = 0; + yylast = -1; + yyexpectaddr = 0; + yybreakondot = 0; + yyvarnext = 0; + yytokentype = 0; + return 0; + } + + if (strchr("=,/;{}()@", c) != NULL) { + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + rval = c; + goto done; + } else if (c == '.') { + if (isbuilding == 0) { + rval = c; + goto done; + } + if (yybreakondot != 0) { + yyunputc(c); + goto done; + } + } + + switch (c) + { + case '-' : + if (yyexpectaddr) + break; + if (isbuilding == 1) + break; + n = yygetc(); + if (n == '>') { + isbuilding = 1; + goto done; + } + yyunputc(n); + rval = '-'; + goto done; + + case '!' : + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + n = yygetc(); + if (n == '=') { + rval = YY_CMP_NE; + goto done; + } + yyunputc(n); + rval = '!'; + goto done; + + case '<' : + if (yyexpectaddr) + break; + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + n = yygetc(); + if (n == '=') { + rval = YY_CMP_LE; + goto done; + } + if (n == '>') { + rval = YY_RANGE_OUT; + goto done; + } + yyunputc(n); + rval = YY_CMP_LT; + goto done; + + case '>' : + if (yyexpectaddr) + break; + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + n = yygetc(); + if (n == '=') { + rval = YY_CMP_GE; + goto done; + } + if (n == '<') { + rval = YY_RANGE_IN; + goto done; + } + yyunputc(n); + rval = YY_CMP_GT; + goto done; + } + + /* + * Now for the reason this is here...IPv6 address parsing. + * The longest string we can expect is of this form: + * 0000:0000:0000:0000:0000:0000:000.000.000.000 + * not: + * 0000:0000:0000:0000:0000:0000:0000:0000 + */ +#ifdef USE_INET6 + if (yyexpectaddr == 1 && isbuilding == 0 && (ishex(c) || c == ':')) { + char ipv6buf[45 + 1], *s, oc; + int start; + + start = yypos; + s = ipv6buf; + oc = c; + + /* + * Perhaps we should implement stricter controls on what we + * swallow up here, but surely it would just be duplicating + * the code in inet_pton() anyway. + */ + do { + *s++ = c; + c = yygetc(); + } while ((ishex(c) || c == ':' || c == '.') && + (s - ipv6buf < 46)); + yyunputc(c); + *s = '\0'; + + if (inet_pton(AF_INET6, ipv6buf, &yylval.ip6) == 1) { + rval = YY_IPV6; + yyexpectaddr = 0; + goto done; + } + yypos = start; + c = oc; + } +#endif + + if (c == ':') { + if (isbuilding == 1) { + yyunputc(c); + goto done; + } + rval = ':'; + goto done; + } + + if (isbuilding == 0 && c == '0') { + n = yygetc(); + if (n == 'x') { + do { + n = yygetc(); + } while (ishex(n)); + yyunputc(n); + rval = YY_HEX; + goto done; + } + yyunputc(n); + } + + /* + * No negative numbers with leading - sign.. + */ + if (isbuilding == 0 && ISDIGIT(c)) { + do { + n = yygetc(); + } while (ISDIGIT(n)); + yyunputc(n); + rval = YY_NUMBER; + goto done; + } + + isbuilding = 1; + goto nextchar; + +done: + yystr = yytexttostr(0, yypos); + + if (isbuilding == 1) { + wordtab_t *w; + + w = NULL; + isbuilding = 0; + + if ((yyvarnext == 0) && (nokey == 0)) { + w = yyfindkey(yystr); + if (w == NULL && yywordtab != NULL) { + yyresetdict(); + w = yyfindkey(yystr); + } + } else + yyvarnext = 0; + if (w != NULL) + rval = w->w_value; + else + rval = YY_STR; + } + + if (rval == YY_STR && yysavedepth > 0) + yyresetdict(); + + yytokentype = rval; + + if (yydebug) + printf("lexed(%s) [%d,%d,%d] => %d\n", yystr, string_start, + string_end, pos, rval); + + switch (rval) + { + case YY_NUMBER : + sscanf(yystr, "%u", &yylval.num); + break; + + case YY_HEX : + sscanf(yystr, "0x%x", (u_int *)&yylval.num); + break; + + case YY_STR : + yylval.str = strdup(yystr); + break; + + default : + break; + } + + if (yylast > 0) { + bcopy(yytext + yypos, yytext, + sizeof(yytext[0]) * (yylast - yypos + 1)); + yylast -= yypos; + yypos = 0; + } + + return rval; +} + + +static wordtab_t *yyfindkey(key) +char *key; +{ + wordtab_t *w; + + if (yywordtab == NULL) + return NULL; + + for (w = yywordtab; w->w_word != 0; w++) + if (strcasecmp(key, w->w_word) == 0) + return w; + return NULL; +} + + +char *yykeytostr(num) +int num; +{ + wordtab_t *w; + + if (yywordtab == NULL) + return ""; + + for (w = yywordtab; w->w_word; w++) + if (w->w_value == num) + return w->w_word; + return ""; +} + + +wordtab_t *yysettab(words) +wordtab_t *words; +{ + wordtab_t *save; + + save = yywordtab; + yywordtab = words; + return save; +} + + +void yyerror(msg) +char *msg; +{ + char *txt, letter[2]; + int freetxt = 0; + + if (yytokentype < 256) { + letter[0] = yytokentype; + letter[1] = '\0'; + txt = letter; + } else if (yytokentype == YY_STR || yytokentype == YY_HEX || + yytokentype == YY_NUMBER) { + if (yystr == NULL) { + txt = yytexttostr(yypos, YYBUFSIZ); + freetxt = 1; + } else + txt = yystr; + } else { + txt = yykeytostr(yytokentype); + } + fprintf(stderr, "%s error at \"%s\", line %d\n", msg, txt, yylineNum); + if (freetxt == 1) + free(txt); + exit(1); +} + + +void yysetdict(newdict) +wordtab_t *newdict; +{ + if (yysavedepth == sizeof(yysavewords)/sizeof(yysavewords[0])) { + fprintf(stderr, "%d: at maximum dictionary depth\n", + yylineNum); + return; + } + + yysavewords[yysavedepth++] = yysettab(newdict); + if (yydebug) + printf("yysavedepth++ => %d\n", yysavedepth); +} + +void yyresetdict() +{ + if (yysavedepth > 0) { + yysettab(yysavewords[--yysavedepth]); + if (yydebug) + printf("yysavedepth-- => %d\n", yysavedepth); + } +} + + + +#ifdef TEST_LEXER +int main(argc, argv) +int argc; +char *argv[]; +{ + int n; + + yyin = stdin; + + while ((n = yylex()) != 0) + printf("%d.n = %d [%s] %d %d\n", + yylineNum, n, yystr, yypos, yylast); +} +#endif diff --git a/contrib/ipfilter/tools/lexer.h b/contrib/ipfilter/tools/lexer.h new file mode 100644 index 000000000000..4950aa8168dc --- /dev/null +++ b/contrib/ipfilter/tools/lexer.h @@ -0,0 +1,37 @@ +/* $NetBSD$ */ + + +typedef struct wordtab { + char *w_word; + int w_value; +} wordtab_t; + +#ifdef NO_YACC +#define YY_COMMENT 1000 +#define YY_CMP_NE 1001 +#define YY_CMP_LE 1002 +#define YY_RANGE_OUT 1003 +#define YY_CMP_GE 1004 +#define YY_RANGE_IN 1005 +#define YY_HEX 1006 +#define YY_NUMBER 1007 +#define YY_IPV6 1008 +#define YY_STR 1009 +#define YY_IPADDR 1010 +#endif + +#define YYBUFSIZ 8192 + +extern wordtab_t *yysettab __P((wordtab_t *)); +extern void yysetdict __P((wordtab_t *)); +extern int yylex __P((void)); +extern void yyerror __P((char *)); +extern char *yykeytostr __P((int)); +extern void yyresetdict __P((void)); + +extern FILE *yyin; +extern int yylineNum; +extern int yyexpectaddr; +extern int yybreakondot; +extern int yyvarnext; + diff --git a/contrib/ipfilter/typescript b/contrib/ipfilter/typescript new file mode 100644 index 000000000000..1446ac41406c --- /dev/null +++ b/contrib/ipfilter/typescript @@ -0,0 +1,121 @@ +Script started on Mon Apr 25 17:24:29 2005 +/sbin /usr/sbin /bin /usr/bin /etc /usr/sbin +FreeBSD FreeBSD/i386.6.0 on /dev/ttyp0 +tcsh +.cshrc +(.cshrc) +-done. +/bin /sbin /etc /usr/bin /usr/sbin /usr/games +.cshrc done +TERM = vt100 +/usr/X11R6/man /usr/share/man +(freebsd6:~) cd /usr/src/sycontrib/ipfilter +(freebsd6:/usr/src/contrib/ipfilter) l +./ ip_compat.h ipf.h +../ ip_fil.c ipl.h +.cvsignore ip_fil.h iplang/ +BNF ip_fil_freebsd.c ipmon.h +BSD/ ip_frag.c ipsd/ +BugReport ip_frag.h ipsend/ +CVS/ ip_ftp_pxy.c ipt.h +FAQ.FreeBSD ip_h323_pxy.c kmem.h +FWTK/ ip_htable.c l4check/ +FreeBSD/ ip_htable.h lib/ +FreeBSD-2.2/ ip_ipsec_pxy.c man/ +FreeBSD-3/ ip_irc_pxy.c md5.c +FreeBSD-4.0/ ip_log.c md5.h +HISTORY ip_lookup.c mkfilters +IMPORTANT ip_lookup.h mlf_ipl.c +INST.FreeBSD-2.2 ip_msnrpc_pxy.c mlf_rule.c +INSTALL.FreeBSD ip_nat.c mlfk_ipl.c +INSTALL.xBSD ip_nat.h mlfk_rule.c +IPF.KANJI ip_netbios_pxy.c mlh_rule.c +IPFILTER.LICENCE ip_pool.c net/ +Makefile ip_pool.h netinet/ +NAT.FreeBSD ip_pptp_pxy.c opts.h +QNX_OCL.txt ip_proxy.c pcap-ipf.h +README ip_proxy.h perl/ +STYLE.TXT ip_raudio_pxy.c radix.c +WhatsNew40.txt ip_rcmd_pxy.c radix_ipf.h +Y2K ip_rpcb_pxy.c rules/ +bpf-ipf.h ip_rules.c samples/ +bpf_filter.c ip_rules.h snoop.h +bsdinstall ip_scan.c test/ +buildsunos ip_scan.h todo +etc/ ip_state.c tools/ +fil.c ip_state.h typescript +ip_auth.c ip_sync.c +ip_auth.h ip_sync.h +(freebsd6:/usr/src/contrib/ipfilter) l CVS +./ Entries Repository +../ Entries.Log Root +(freebsd6:/usr/src/contrib/ipfilter) \rm -rf CVS +(freebsd6:/usr/src/contrib/ipfilter) l +./ ip_compat.h ip_sync.h +../ ip_fil.c ipf.h +.cvsignore ip_fil.h ipl.h +BNF ip_fil_freebsd.c iplang/ +BSD/ ip_frag.c ipmon.h +BugReport ip_frag.h ipsd/ +FAQ.FreeBSD ip_ftp_pxy.c ipsend/ +FWTK/ ip_h323_pxy.c ipt.h +FreeBSD/ ip_htable.c kmem.h +FreeBSD-2.2/ ip_htable.h l4check/ +FreeBSD-3/ ip_ipsec_pxy.c lib/ +FreeBSD-4.0/ ip_irc_pxy.c man/ +HISTORY ip_log.c md5.c +IMPORTANT ip_lookup.c md5.h +INST.FreeBSD-2.2 ip_lookup.h mkfilters +INSTALL.FreeBSD ip_msnrpc_pxy.c mlf_ipl.c +INSTALL.xBSD ip_nat.c mlf_rule.c +IPF.KANJI ip_nat.h mlfk_ipl.c +IPFILTER.LICENCE ip_netbios_pxy.c mlfk_rule.c +Makefile ip_pool.c mlh_rule.c +NAT.FreeBSD ip_pool.h net/ +QNX_OCL.txt ip_pptp_pxy.c netinet/ +README ip_proxy.c opts.h +STYLE.TXT ip_proxy.h pcap-ipf.h +WhatsNew40.txt ip_raudio_pxy.c perl/ +Y2K ip_rcmd_pxy.c radix.c +bpf-ipf.h ip_rpcb_pxy.c radix_ipf.h +bpf_filter.c ip_rules.c rules/ +bsdinstall ip_rules.h samples/ +buildsunos ip_scan.c snoop.h +etc/ ip_scan.h test/ +fil.c ip_state.c todo +ip_auth.c ip_state.h tools/ +ip_auth.h ip_sync.c typescript +(freebsd6:/usr/src/contrib/ipfilter) cd .. +(freebsd6:/usr/src/contrib) mv ipfilter ipfilter.i +(freebsd6:/usr/src/contrib) cd !$ipfilter.i +(freebsd6:/usr/src/contrib/ipfilter.i) l */CVS +/bin/ls: No match. +(freebsd6:/usr/src/contrib/ipfilter.i) cvs m +(freebsd6:/usr/src/contrib/ipfilter.i) cvs import +(freebsd6:/usr/src/contrib/ipfilter.i) ~ +/home/darrenr: Permission denied. +(freebsd6:/usr/src/contrib/ipfilter.i) ~ +(freebsd6:/usr/src/contrib/ipfilter.i) suspend +(freebsd6:/usr/src/contrib/ipfilter.i) history + 1 17:24 cd /usr/src/contrib/ipfilter + 2 17:24 l + 3 17:24 l CVS + 4 17:24 \rm -rf CVS + 5 17:24 l + 6 17:24 cd .. + 7 17:24 mv ipfilter ipfilter.i + 8 17:24 cd ipfilter.i + 9 17:24 l */CVS + 10 17:25 ~ + 11 17:25 suspend + 12 17:25 history +(freebsd6:/usr/src/contrib/ipfilter.i) +(freebsd6:/usr/src/contrib/ipfilter.i) kill -STOP $$ + +^C +c + + +(freebsd6:/usr/src/contrib/ipfilter.i) +(freebsd6:/usr/src/contrib/ipfilter.i) c +