#! /bin/bash # This is a wrapper script to simulate ipfwadm 2.3a. It ain't pretty, # but it should work (for valid commands). `-V' is translated to `-W' # or ignored if a `-W' option is already there, but always warned # about. # Paul ``Rusty'' Russell, Nov-1997. ipchains@rustcorp.com. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Version: 1.0.1: Fixed -t (no longer de-hexizes). # # Version: 1.0.2: Fixed undocumented `-a masq'. # Should be OK now with bash v1. # If we can't find ip_fwnames, call /sbin/ipfwadm.real # # Version: 1.1: Fixed printing counts for accounting chains list. # Fixed -A -z and -A -f cases to do all 3 acct. rules. # # Version: 1.1.1: Fixed syntax error by escaping ( and ). # # Version: 1.1.2: Fixed REDIR thanks to Ambrose Li. # Fixed "printf --" thanks to Alain Knaff. # Fixed masquerade policy # Fixed bug report message unquoted `;'. # Fixed -k/-y and -S/-D options [ found by Charlie Brady ] # Barf on all ipchains failures. if [ -n "$DEBUG_IPFWADM" ]; then IPCHAINS=print_ipchains; else IPCHAINS=/sbin/ipchains; fi PROC_FIREWALL_NAMES="/proc/net/ip_fwnames" SPECIAL_CHAIN="IpFwAdM!" START_MARK=10000 barf() { echo "$@" echo echo If this command worked with the original ipfwadm 2.3, please echo submit a bug report to \`ipchains@rustcorp.com\'. Note that you echo now need to be root, even to list the chains \(complain to Alan Cox\). echo echo The best way to do this is to submit the output of \`$0 --version\', echo the command used to obtain this error, any previous ipfwadm echo commands, and the output of \`ipchains-save\'. echo echo Then try flushing all the rules \`ipchains -F\; ipchains -X\', echo setting the DEBUG_IPFWADM variable \`export DEBUG_IPFWADM=1\' or echo \`setenv DEBUG_IPFWADM 1\' and rerunning the command\(s\) which echo caused this error. exit 1 } print_ipchains() { echo ipchains "$@" 1>&2 /sbin/ipchains "$@" } setup_chains() { if [ `wc -l < $PROC_FIREWALL_NAMES` != 3 -a -z "$DEBUG_IPFWADM" ] then echo You cannot mix the \`ipfwadm\' wrapper with ipchains. 1>&2 echo You must delete all user chains and flush all built-in chains 1>&2 echo if you want to use the \`ipfwadm\' wrapper. 1>&2 exit 1 fi $IPCHAINS -N acctin $IPCHAINS -N acctout $IPCHAINS -N acctboth $IPCHAINS -N inp $IPCHAINS -N out $IPCHAINS -N fwd # Let all fragments through like the old code used to. $IPCHAINS -A input -f -j ACCEPT $IPCHAINS -A output -f -j ACCEPT $IPCHAINS -A forward -f -j ACCEPT # Jump to accounting rules. Order of traversal of acct rules # doesn't matter. $IPCHAINS -A input -j acctin $IPCHAINS -A input -j acctboth $IPCHAINS -A output -j acctout $IPCHAINS -A output -j acctboth # Now go to `real' chains. $IPCHAINS -A input -j inp $IPCHAINS -A output -j out $IPCHAINS -A forward -j fwd # Create dummy chains to mark this as an ipfwadm-emulation firewall. $IPCHAINS -N $SPECIAL_CHAIN # Insert min and max mark values. $IPCHAINS -A $SPECIAL_CHAIN -m $START_MARK $IPCHAINS -A $SPECIAL_CHAIN -m $(($START_MARK + 1)) } # SIGH. We use identical marks to indicate which rules are actually # the same rule (to simulate multiple ports, and -y without -P tcp). # We start the marks at 1,000,000, so we can insert before them or append # after them. # In the accounting chain, marks are unique between the three acct* chains, # so we can tell ordering. print_count() { count=$(($1)) if let $(($count > 99999)) then cntkb=$((($count + 500) / 1000)) if let $((cntkb > 9999)) then cntmb=$((($count + 500000) / 1000000)) printf "%4sM " $cntmb else printf "%4sK " $cntkb fi else printf "%5s " $count fi } dump_rule() { # ARGS: $LIST_VERBOSE $EXPAND_NUMBERS $BIDIR $SYN_NO_PROTO $SRCPORTS $DSTPTS # $PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX $IFNM $NUM $SRCIP $DSTIP $REDIR # $PRINT_COUNTS # The ipfwadm code looks like: (* = -e only) # * * * * * * * # pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR if [ -n "$1" -o -n "${19}" ] then # Packet and byte counts. if [ -n "$2" ]; then printf "%8u " $7; else print_count $7; fi if [ -n "$2" ]; then printf "%8u " $8; else print_count $8; fi fi # Kind case "$9" in in) printf "%-3s " "$9" ;; out) printf "%-3s " "$9" ;; i/o) printf "%-3s " "$9" ;; *) printf "%-5s " "$9" ;; esac # Proto printf "%-5s" "${10}" if [ -n "$1" ] then # Flags if [ "$3" != 0 ]; then printf "b"; else printf "%s" "-"; fi case "${11}" in *!y*) printf "k-" ;; *y*) printf "%s" "-y" ;; *) printf "%s" "--" ;; esac case "${11}" in *l*) printf "l " ;; *) printf "%s" "- " ;; esac # TOS printf "${12} ${13} " # Interface name printf "%-7.16s " "${14}" # Interface address if [ -n "${15}" ]; then printf "%-15s " 0.0.0.0; else printf "%-15s " any; fi fi # Source and dest. printf "%-20s " "${16}" printf "%-20s" "${17}" # Source Ports. if [ "${10}" != tcp -a "${10}" != udp -a "${10}" != icmp ] then echo " n/a" return fi printf " " printf "$5" | tr ' ' ',' if [ "${10}" = icmp ] then echo return fi # Dest ports. if [ "$5" != "n/a" ] then printf " -> " printf "$6" | tr ' ' ',' fi # redirect ports. if [ "$9" = "acc/r" ] then printf " => %s" "${18}" fi echo } get_policy() # CHAIN { case "`ipchains -L $1 | head -1`" in *ACCEPT*) echo accept;; *MASQ*) echo accept/masquerade;; *REJECT*) echo reject;; *DENY*) echo deny;; *) barf "Unknown policy for \`$1' - `ipchains -L $1 2>&1`" esac } list_chain() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS { # if (!(format & FMT_NOCOUNTS)) { # if (format & FMT_KILOMEGA) { # fprintf(fp, FMT("%5s ","%s "), "pkts"); # fprintf(fp, FMT("%5s ","%s "), "bytes"); # } else { # fprintf(fp, FMT("%8s ","%s "), "pkts"); # fprintf(fp, FMT("%10s ","%s "), "bytes"); # } # } IS_ACCT="" case "$1" in acct*) IS_ACCT="Y";; inp) printf "IP firewall input rules, default policy: " get_policy input ;; out) printf "IP firewall output rules, default policy: " get_policy output ;; fwd) printf "IP firewall forward rules, default policy: " get_policy forward ;; *) barf "Unknown chain for list_chain - \`$1'" ;; esac if [ -n "$2" -o -n "$IS_ACCT" ] then if [ -z "$4" ] then printf "%5s " pkts printf "%5s " bytes else printf "%8s " pkts printf "%10s " bytes fi fi # if (!(format & FMT_NOKIND)) { # if (chain == CHN_ACCT) # fprintf(fp, FMT("%-3s ","%s "), "dir"); # else # fprintf(fp, FMT("%-5s ","%s "), "type"); # } case "$1" in acct*) printf "%-3s " dir ;; *) printf "%-5s " type ;; esac # fputs("prot ", fp); printf "prot " # if (format & FMT_OPTIONS) # fputs("opt ", fp); # if (format & FMT_TOS) # fputs("tosa tosx ", fp); # if (format & FMT_VIA) { # fprintf(fp, FMT("%-7s ","(%s "), "ifname"); # fprintf(fp, FMT("%-15s ","%s) "), "ifaddress"); # } if [ -n "$2" ] then printf "opt tosa tosx %-7s %-15s " ifname ifaddress fi # fprintf(fp, FMT("%-20s ","%s "), "source"); # fprintf(fp, FMT("%-20s ","%s "), "destination"); # fputs("ports\n", fp); # } printf "%-20s %-20s ports" source destination echo case "$1" in acct*) shift; (list_chain_real acctin "$@" "1" "1" list_chain_real acctout "$@" "1" "1" list_chain_real acctboth "$@" "1" "1") | sort -n | cut -c11-;; *) list_chain_real "$@" ;; esac } list_chain_real() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS $PRINT_COUNTS $PREPEND_MARK { CHAIN="$1" LIST_VERBOSE="$2" NUMERIC="$3" EXPAND_NUMBERS="$4" PRINT_COUNTS="$5" PREPEND_MARK="$6" # The ipfwadm code looks like: (* = -e only) # * * * * * * * # pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR # # The ipchains code looks like: (* = -v only) # * * * * * * * # pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR LAST_MARK=xxx BIDIR=0 SYN_NO_PROTO=0 SRCPORTS="" DSTPORTS="" [ -z "$NUMERIC" ] || NUMERIC="-n" $IPCHAINS -L $CHAIN -v -x $NUMERIC | tail +3 | while true do if ! read PCNT BCNT TARG PROTO FLAGS TOSA TOSX IFNM MARK SRCIP DSTIP SRCPTS IGN1 DSTPTS REDIR then # Dump last rule. if [ "$LAST_MARK" != "xxx" ] then [ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK" dump_rule "$LIST_VERBOSE" "$EXPAND_NUMBERS" $BIDIR $SYN_NO_PROTO "$SRCPORTS" "$DSTPORTS" $LAST_PCNT $LAST_BCNT $LAST_TARG $LAST_PROTO $LAST_FLAGS $LAST_TOSA $LAST_TOSX "$LAST_IFNM" "$NUMERIC" $LAST_SRCIP $LAST_DSTIP "$LAST_REDIR" "$PRINT_COUNTS" fi return fi [ -z "$DEBUG_IPFWADM" ] || echo RULE is "$PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX "$IFNM" $MARK $SRCIP $DSTIP $SRCPTS $IGN1 $DSTPTS $REDIR" 1>&2 if [ "$LAST_MARK" = "$MARK" ] then # Fold rules back together. # We combine for any of the following reasons: # -k or -y used with no protocol: first rule has proto TCP and 'y'. # -b used: SRC & DST reversed. # Multiple ports: all the same but for port. # Worst cases: # ipfwadm -I -a accept -b -P tcp -S 0/0 1 4 -D 1/1 5 9 # => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR # ? ? ? TCP ? ? ? ? ? 0/0 1/1 1 5 # ? ? ? TCP ? ? ? ? ? 1/1 0/0 5 1 # ? ? ? TCP ? ? ? ? ? 0/0 1/1 1 9 # ? ? ? TCP ? ? ? ? ? 1/1 0/0 9 1 # ? ? ? TCP ? ? ? ? ? 0/0 1/1 4 5 # ? ? ? TCP ? ? ? ? ? 1/1 0/0 5 4 # ? ? ? TCP ? ? ? ? ? 0/0 1/1 4 9 # ? ? ? TCP ? ? ? ? ? 1/1 0/0 9 4 # # ipfwadm -I -a accept -b -y -S 0/0 -D 1/1 # => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR # ? ? ? TCP ?y?? ? ? ? ? 0/0 1/1 # ? ? ? TCP ?y?? ? ? ? ? 1/1 0/0 # ? ? ? ANY ?-?? ? ? ? ? 0/0 1/1 # ? ? ? ANY ?-?? ? ? ? ? 1/1 0/0 # if [ -n "$DEBUG_IPFWADM" ] # then # echo LAST_PROTO = \`"$LAST_PROTO"\' # echo PROTO = \`"$PROTO"\' # echo LAST_SRCIP = \`"$LAST_SRCIP"\' # echo DSTIP = \`"$DSTIP"\' # echo LAST_DSTIP = \`"$LAST_DSTIP"\' # echo SRCIP = \`"$SRCIP"\' # echo LAST_SRCPTS = \`"$LAST_SRCPTS"\' # echo DSTPTS = \`"$DSTPTS"\' # echo LAST_DSTPTS = \`"$LAST_DSTPTS"\' # echo SRCPTS = \`"$SRCPTS"\' # fi if [ "$LAST_PROTO" = \!tcp -a "$PROTO" = tcp ] then [ -n "$DEBUG_IPFWADM" ] && echo "Found SYN rule." SYN_NO_PROTO=1 PCNT=$(($LAST_PCNT + $PCNT)) BCNT=$(($LAST_BCNT + $BCNT)) PROTO="all" elif [ "$LAST_SRCIP" = "$DSTIP" -a "$LAST_DSTIP" = "$SRCIP" -a "$LAST_SRCPTS" = "$DSTPTS" -a "$LAST_DSTPTS" = "$SRCPTS" ] then [ -n "$DEBUG_IPFWADM" ] && echo "Found bidir rule." BIDIR=1 LAST_PCNT=$(($LAST_PCNT + $PCNT)) LAST_BCNT=$(($LAST_BCNT + $BCNT)) # Don't transfer this rule to LAST_ vars - effectively ignore. continue; else [ -n "$DEBUG_IPFWADM" ] && echo "Found port rule." # For n source ports and m dest ports, there will be # n x m rules. So, we add to SRCPORTS when we see a new # SRCPTS, but only add to DSTPORTS for the first SRCPORTS. if [ "$SRCPTS" != "$LAST_SRCPTS" ] then SRCPORTS="$SRCPORTS $SRCPTS" fi if [ "$SRCPORTS" = "$SRCPTS" ] then DSTPORTS="$DSTPORTS $DSTPTS" fi PCNT=$(($LAST_PCNT + $PCNT)) BCNT=$(($LAST_BCNT + $BCNT)) fi else # Dump last rule. if [ "$LAST_MARK" != "xxx" ] then [ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK" dump_rule "$LIST_VERBOSE" "$EXPAND_NUMBERS" $BIDIR $SYN_NO_PROTO "$SRCPORTS" "$DSTPORTS" $LAST_PCNT $LAST_BCNT $LAST_TARG $LAST_PROTO $LAST_FLAGS $LAST_TOSA $LAST_TOSX "$LAST_IFNM" "$NUMERIC" $LAST_SRCIP $LAST_DSTIP "$LAST_REDIR" "$PRINT_COUNTS" fi BIDIR=0 SYN_NO_PROTO=0 SRCPORTS="$SRCPTS" DSTPORTS="$DSTPTS" fi # Save for next iteration, in case mark the same. LAST_PCNT=$PCNT LAST_BCNT=$BCNT LAST_PROTO=$PROTO LAST_FLAGS=$FLAGS LAST_TOSA=$TOSA LAST_TOSX=$TOSX LAST_IFNM="$IFNM" LAST_MARK=$MARK LAST_SRCIP=$SRCIP LAST_DSTIP=$DSTIP LAST_REDIR="$REDIR" LAST_SRCPTS="$SRCPTS" LAST_DSTPTS="$DSTPTS" case "$CHAIN" in acctin) LAST_TARG=in ;; acctout) LAST_TARG=out ;; acctboth) LAST_TART=i/o ;; *) case "$TARG" in REDIRECT) LAST_TARG="acc/r" ;; MASQ) LAST_TARG="acc/m" ;; ACCEPT) LAST_TARG="acc" ;; REJECT) LAST_TARG="rej" ;; DENY) LAST_TARG="deny" ;; *) barf Unknown target \`"$TARG"\'. ;; esac ;; esac done } ############################################################################ if [ ! -f $PROC_FIREWALL_NAMES ] then if [ -f /proc/net/ip_input -o -f /proc/net/ip_acct ] then # Old kernel. Let's play nice. [ -x /sbin/ipfwadm.real ] && exec /sbin/ipfwadm.real "$@" fi echo "Generic IP Firewall Chains not in this kernel" 1>&2 exit 1 fi while [ $# != 0 ] do case "$1" in -A) case x"$2" in x-*) CHAIN=acctboth ;; xboth) CHAIN=acctboth; shift ;; xin) CHAIN=acctin; shift ;; xout) CHAIN=acctout; shift ;; x) CHAIN=acctboth ;; *) barf Unknown option \`"$2"\' ;; esac ;; -I) CHAIN=inp ;; -O) CHAIN=out ;; -F) CHAIN=fwd ;; -M) MASQ_MODE=1 ;; -a) COMMAND=-A case x"$2" in x-*) TARGET="" ;; x) TARGET="" ;; xr*) TARGET=REJECT; shift ;; xd*) TARGET=DENY; shift ;; xa*) TARGET=ACCEPT; shift ;; xm*) TARGET=ACCEPT; MASQ=1; shift ;; *) barf Unknown policy for append: \`"$2"\' ;; esac ;; -i) COMMAND="-I " case x"$2" in x-*) TARGET="" ;; x) TARGET="" ;; xr*) TARGET=REJECT; shift ;; xd*) TARGET=DENY; shift ;; xa*) TARGET=ACCEPT; shift ;; *) barf Unknown policy for insert: \`"$2"\' ;; esac ;; -d) COMMAND=-D case x"$2" in x-*) TARGET="" ;; x) TARGET="" ;; xr*) TARGET=REJECT; shift ;; xd*) TARGET=DENY; shift ;; xa*) TARGET=ACCEPT; shift ;; *) barf Unknown policy for delete: \`"$2"\' ;; esac ;; -l) LIST=1 ;; -z) COMMAND=-Z ;; -f) COMMAND=-F ;; -p) COMMAND=-P case "$2" in r*) TARGET=REJECT; shift ;; d*) TARGET=DENY; shift ;; a*) TARGET=ACCEPT; shift ;; m*) TARGET=MASQ; shift ;; *) barf Unknown policy for -p: \`"$2"\' ;; esac ;; -s) COMMAND=-S OPTIONS="$2 $3 $4" shift 3 ;; -c) COMMAND=-C ;; -h) print_help ;; -P) PROTOCOL="-p $2" shift ;; -S) SRC_OPTIONS="-s $2" shift while true do case x"$2" in x) break ;; x-*) break ;; x?*) SRC_PORTS="$2 $SRC_PORTS" ;; esac shift done ;; -D) DST_OPTIONS="-d $2" shift while true do case x"$2" in x) break ;; x-*) break ;; x?*) DST_PORTS="$2 $DST_PORTS" ;; esac shift done ;; -V) VIA_ADDR="$2" shift ;; -W) INTERFACE="$2" OPTIONS="$OPTIONS -i $2" shift ;; -b) OPTIONS="$OPTIONS -b" ;; -e) LIST_VERBOSE=1 ;; -k) TCPSYN="! -y" ;; -m) MASQ=1 ;; -n) NUMERIC=1 ;; -o) OPTIONS="$OPTIONS -l" ;; -r) case x"$2" in x-*) REDIR=0 ;; x) REDIR=0 ;; x?*) REDIR="$2"; shift ;; esac ;; -t) TOSAND=$(($2 | 0x01)) TOSXOR=$(($3 & 0xFE)) OPTIONS="$OPTIONS -t "`printf "0x%02x 0x%02x" $TOSAND $TOSXOR` shift 2 ;; -v) OPTIONS="$OPTIONS -v" ;; -x) EXPAND_NUMBERS=1; ;; -y) TCPSYN="-y" ;; --version) echo "ipfwadm wrapper version 1.1.2" exit 0 ;; -??*) echo "ERROR: Please separate arguments, eg \`-Mle' => \`-M -l -e'." >&2 exit 1 ;; *) barf Unexpected argument \`"$1"\'. ;; esac shift done # Variables to worry about: # $CHAIN - actual chain to work on. # X$MASQ_MODE - set if -M given. # X$COMMAND - set if this is a simple command conversion. # X$TARGET - set for COMMAND of -A, -I, -D or -P (but see REDIR and MASQ). # X$LIST - set if they want a list. # X$NUMERIC - list with -n. # X$LIST_VERBOSE - list all info. # X$EXPAND_NUMBERS - list full numbers. # X$OPTIONS - miscellaneous easy-to-convert options. # X$SRC_OPTIONS - set if a source address is specified. # X$SRC_PORTS - space-separated list of specified source ports/ranges. # X$DST_OPTIONS - set if a dest address is specified. # X$DST_PORTS - space-separated list of specified dest ports/ranges. # $VIA_ADDR - an interface address if one is specified. # $INTERFACE - an interface name if one is specified. # X$TCPSYN - set if `-k' or `-y' is specified. # X$MASQ - set if `-m' is specified. # X$REDIR - set to the port if `-r port' is specified if [ -n "$MASQ_MODE" ] then if [ -n "$LIST" ] then $IPCHAINS -M -L $OPTIONS else $IPCHAINS $COMMAND $OPTIONS fi elif [ -n "$LIST" ] then if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES then echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2 exit 0 fi # Construct a list. if [ x$COMMAND = x-Z ] then # We have to atomically zero and list a chain. This is # currently impossible, so we: # 1) stop all packets on the given chain. # 2) list the values. # 3) clear the counters. # 4) resume on the given chain. case "$CHAIN" in acct*) $IPCHAINS -I 1 input -j DENY $IPCHAINS -I 1 output -j DENY ;; inp) $IPCHAINS -I 1 input -j DENY ;; out) $IPCHAINS -I 1 output -j DENY ;; fwd) $IPCHAINS -I 1 forward -j DENY ;; *) barf Unknown chain to stop: \`"$CHAIN"\'. esac list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS" $IPFWADM -Z $CHAIN case "$CHAIN" in acct*) $IPCHAINS -D 1 input $IPCHAINS -D 1 output ;; inp) $IPCHAINS -D 1 input ;; out) $IPCHAINS -D 1 output ;; fwd) $IPCHAINS -D 1 forward ;; *) barf Unknown chain to restart: \`"$CHAIN"\'. esac else list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS" fi elif [ x"$COMMAND" = x"-F" -o x"$COMMAND" = x"-Z" -o x"$COMMAND" = x"-C" ] then if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES then echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2 exit 0 fi if [ "$CHAIN" = acctboth ] then # Do it to all of them. $IPCHAINS $COMMAND acctin $OPTIONS $IPCHAINS $COMMAND acctout $OPTIONS fi $IPCHAINS $COMMAND $CHAIN $OPTIONS else grep -q IpFwAdM! < $PROC_FIREWALL_NAMES || setup_chains # Figure out what the target should be. if [ -n "$REDIR" ] then TARGET="REDIRECT $REDIR" elif [ -n "$MASQ" ] then TARGET=MASQ fi if [ x"$COMMAND" = x"-P" ] then case "$CHAIN" in inp) CHAIN=input ;; out) CHAIN=output ;; fwd) CHAIN=forward ;; *) barf Illegal chain for -P: \`"$CHAIN"\'.;; esac $IPCHAINS $COMMAND $CHAIN $TARGET $OPTIONS else # If they used -V, and not -W, then try to figure out interface # name. ALWAYS warn about difference. if [ -n "$VIA_ADDR" ] then if [ -n "$INTERFACE" ] then echo Warning: \`-V $VIA_ADDR\' option ignored\; using \`-W $INTERFACE\' only. else INTERFACE=`ifconfig | awk -v ADDR=$VIA_ADDR '/^[a-z0-9A-Z]/ { IFNAME=$1 } $0 ~ "^[^A-Za-z0-9:]*inet addr:" ADDR { print IFNAME}'` if [ -z "$INTERFACE" ] then echo Can\'t handle -V option: can\'t find interface name for the address \`$VIA_ADDR\'. 1>&2 echo Please replace the -V with the appropriate -W option. 1>&2 exit 1 fi echo Replacing \`-V $VIA_ADDR\' with \`-W $INTERFACE\'. OPTIONS="$OPTIONS -i $INTERFACE" fi fi # Insert, append or delete. case $COMMAND in # For Insert, get (and decrement) minimal mark #. -I*) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -3 | tail -1); echo $9) $IPCHAINS -R $SPECIAL_CHAIN 1 -m $(($MARK - 1)) MARK="-m $MARK" ;; # For Append, get (and increment) maximum mark #. -A) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -4 | tail -1); echo $9) $IPCHAINS -R $SPECIAL_CHAIN 2 -m $(($MARK + 1)) MARK="-m $MARK" ;; esac # Only care about TCP SYN if -p TCP not specified. if [ -n "$TCPSYN" ] then case "$PROTOCOL" in *[Tt][Cc][Pp]) OPTIONS="$OPTIONS $PROTOCOL $TCPSYN" TCPSYN="" ;; esac else OPTIONS="$OPTIONS $PROTOCOL" fi # Mangle source port and dest port args. if [ -z "$SRC_PORTS" ]; then SRC_PORTS="X"; fi if [ -z "$DST_PORTS" ]; then DST_PORTS="X"; fi [ -n "$TARGET" ] && TARGET="-j $TARGET" for SRC in $SRC_PORTS do if [ $SRC = "X" ]; then SRC=""; fi for DST in $DST_PORTS do if [ $DST = "X" ]; then DST=""; fi if [ -n "$TCPSYN" ] then $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS -p ! tcp $TARGET $MARK || barf "ipchains failed!" $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS -p tcp $TCPSYN $TARGET $MARK || barf "ipchains failed!" else $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS $TARGET $MARK || barf "ipchains failed!" fi done done fi fi