ipfwadm-wrapper
上传用户:shbosideng
上传日期:2013-05-04
资源大小:1555k
文件大小:21k
源码类别:

SNMP编程

开发平台:

C/C++

  1. #! /bin/bash
  2. # This is a wrapper script to simulate ipfwadm 2.3a.  It ain't pretty,
  3. # but it should work (for valid commands).  `-V' is translated to `-W'
  4. # or ignored if a `-W' option is already there, but always warned
  5. # about.
  6. # Paul ``Rusty'' Russell, Nov-1997.  ipchains@rustcorp.com.
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. #
  21. # Version: 1.0.1: Fixed -t (no longer de-hexizes).
  22. #
  23. # Version: 1.0.2: Fixed undocumented `-a masq'.
  24. #                 Should be OK now with bash v1.
  25. #                 If we can't find ip_fwnames, call /sbin/ipfwadm.real
  26. #
  27. # Version: 1.1: Fixed printing counts for accounting chains list.
  28. # Fixed -A -z and -A -f cases to do all 3 acct. rules.
  29. #
  30. # Version: 1.1.1: Fixed syntax error by escaping ( and ).
  31. #
  32. # Version: 1.1.2: Fixed REDIR thanks to Ambrose Li.
  33. #   Fixed "printf --" thanks to Alain Knaff.
  34. #   Fixed masquerade policy
  35. #   Fixed bug report message unquoted `;'.
  36. #   Fixed -k/-y and -S/-D options [ found by Charlie Brady ]
  37. #   Barf on all ipchains failures.
  38. if [ -n "$DEBUG_IPFWADM" ]; then IPCHAINS=print_ipchains;
  39. else IPCHAINS=/sbin/ipchains;
  40. fi
  41. PROC_FIREWALL_NAMES="/proc/net/ip_fwnames"
  42. SPECIAL_CHAIN="IpFwAdM!"
  43. START_MARK=10000
  44. barf()
  45. {
  46.     echo "$@"
  47.     echo
  48.     echo If this command worked with the original ipfwadm 2.3, please
  49.     echo submit a bug report to `ipchains@rustcorp.com'.  Note that you
  50.     echo now need to be root, even to list the chains (complain to Alan Cox).
  51.     echo
  52.     echo The best way to do this is to submit the output of `$0 --version',
  53.     echo the command used to obtain this error, any previous ipfwadm
  54.     echo commands, and the output of `ipchains-save'.
  55.     echo
  56.     echo Then try flushing all the rules `ipchains -F; ipchains -X',
  57.     echo setting the DEBUG_IPFWADM variable `export DEBUG_IPFWADM=1' or
  58.     echo `setenv DEBUG_IPFWADM 1' and rerunning the command(s) which
  59.     echo caused this error.
  60.     exit 1
  61. }
  62. print_ipchains()
  63. {
  64.     echo ipchains "$@" 1>&2
  65.     /sbin/ipchains "$@"
  66. }
  67. setup_chains()
  68. {
  69.     if [ `wc -l < $PROC_FIREWALL_NAMES` != 3 -a -z "$DEBUG_IPFWADM" ]
  70.     then
  71. echo You cannot mix the `ipfwadm' wrapper with ipchains. 1>&2
  72. echo You must delete all user chains and flush all built-in chains 1>&2
  73. echo if you want to use the `ipfwadm' wrapper. 1>&2
  74. exit 1
  75.     fi
  76.     $IPCHAINS -N acctin
  77.     $IPCHAINS -N acctout
  78.     $IPCHAINS -N acctboth
  79.     $IPCHAINS -N inp
  80.     $IPCHAINS -N out
  81.     $IPCHAINS -N fwd
  82.     # Let all fragments through like the old code used to.
  83.     $IPCHAINS -A input -f -j ACCEPT
  84.     $IPCHAINS -A output -f -j ACCEPT
  85.     $IPCHAINS -A forward -f -j ACCEPT
  86.     # Jump to accounting rules.  Order of traversal of acct rules
  87.     # doesn't matter.
  88.     $IPCHAINS -A input -j acctin
  89.     $IPCHAINS -A input -j acctboth
  90.     $IPCHAINS -A output -j acctout
  91.     $IPCHAINS -A output -j acctboth
  92.     # Now go to `real' chains.
  93.     $IPCHAINS -A input -j inp
  94.     $IPCHAINS -A output -j out
  95.     $IPCHAINS -A forward -j fwd
  96.     # Create dummy chains to mark this as an ipfwadm-emulation firewall.
  97.     $IPCHAINS -N $SPECIAL_CHAIN
  98.     # Insert min and max mark values.
  99.     $IPCHAINS -A $SPECIAL_CHAIN -m $START_MARK
  100.     $IPCHAINS -A $SPECIAL_CHAIN -m $(($START_MARK + 1))
  101. }
  102. # SIGH.  We use identical marks to indicate which rules are actually
  103. # the same rule (to simulate multiple ports, and -y without -P tcp).
  104. # We start the marks at 1,000,000, so we can insert before them or append
  105. # after them.
  106. # In the accounting chain, marks are unique between the three acct* chains,
  107. # so we can tell ordering.
  108. print_count()
  109. {
  110.     count=$(($1))
  111.     if let $(($count > 99999))
  112.     then
  113. cntkb=$((($count + 500) / 1000))
  114. if let $((cntkb > 9999))
  115. then
  116.     cntmb=$((($count + 500000) / 1000000))
  117.     printf "%4sM " $cntmb
  118. else
  119.     printf "%4sK " $cntkb
  120. fi
  121.     else
  122. printf "%5s " $count
  123.     fi
  124. }
  125. dump_rule()
  126. {
  127. # ARGS: $LIST_VERBOSE $EXPAND_NUMBERS $BIDIR $SYN_NO_PROTO $SRCPORTS $DSTPTS
  128. # $PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX $IFNM $NUM $SRCIP $DSTIP $REDIR
  129. # $PRINT_COUNTS
  130. # The ipfwadm code looks like: (* = -e only)
  131. # *    *               *    *    *    *    *       
  132. # pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR
  133.     if [ -n "$1" -o -n "${19}" ]
  134.     then
  135. # Packet and byte counts.
  136. if [ -n "$2" ]; then printf "%8u " $7; else print_count $7; fi
  137. if [ -n "$2" ]; then printf "%8u " $8; else print_count $8; fi
  138.     fi
  139.     # Kind
  140.     case "$9" in
  141. in) printf "%-3s " "$9" ;;
  142. out) printf "%-3s " "$9" ;;
  143. i/o) printf "%-3s " "$9" ;;
  144. *) printf "%-5s " "$9" ;;
  145.     esac
  146.     # Proto
  147.     printf "%-5s" "${10}"
  148.     if [ -n "$1" ]
  149.     then
  150. # Flags
  151. if [ "$3" != 0 ]; then printf "b"; else printf "%s" "-"; fi
  152. case "${11}" in
  153.     *!y*) printf "k-" ;;
  154.     *y*) printf "%s" "-y" ;;
  155.     *) printf "%s" "--" ;;
  156. esac
  157. case "${11}" in
  158.     *l*) printf "l " ;;
  159.     *) printf "%s" "- " ;;
  160. esac
  161. # TOS
  162. printf "${12} ${13} "
  163. # Interface name
  164. printf "%-7.16s " "${14}"
  165. # Interface address
  166. if [ -n "${15}" ]; then printf "%-15s " 0.0.0.0;
  167. else printf "%-15s " any;
  168. fi
  169.     fi
  170.     # Source and dest.
  171.     printf "%-20s " "${16}"
  172.     printf "%-20s" "${17}"
  173.     # Source Ports.
  174.     if [ "${10}" != tcp -a "${10}" != udp -a "${10}" != icmp ]
  175.     then
  176. echo " n/a"
  177. return
  178.     fi
  179.     printf " "
  180.     printf "$5" | tr ' ' ','
  181.     if [ "${10}" = icmp ]
  182.     then
  183. echo
  184. return
  185.     fi
  186.     # Dest ports.
  187.     if [ "$5" != "n/a" ]
  188.     then
  189. printf " -> " 
  190. printf "$6" | tr ' ' ','
  191.     fi
  192.     # redirect ports.
  193.     if [ "$9" = "acc/r" ]
  194.     then
  195. printf " => %s" "${18}"
  196.     fi
  197.     echo
  198. }
  199. get_policy() # CHAIN
  200. {
  201.     case "`ipchains -L $1 | head -1`" in
  202.     *ACCEPT*)
  203. echo accept;;
  204.     *MASQ*)
  205. echo accept/masquerade;;
  206.     *REJECT*)
  207. echo reject;;
  208.     *DENY*)
  209. echo deny;;
  210.     *)
  211. barf "Unknown policy for `$1' - `ipchains -L $1 2>&1`"
  212.     esac
  213. }
  214. list_chain() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS
  215. {
  216. # if (!(format & FMT_NOCOUNTS)) {
  217. #  if (format & FMT_KILOMEGA) {
  218. #  fprintf(fp, FMT("%5s ","%s "), "pkts");
  219. #  fprintf(fp, FMT("%5s ","%s "), "bytes");
  220. #  } else {
  221. #  fprintf(fp, FMT("%8s ","%s "), "pkts");
  222. #  fprintf(fp, FMT("%10s ","%s "), "bytes");
  223. #  }
  224. # }
  225.     IS_ACCT=""
  226.     case "$1" in
  227.     acct*) IS_ACCT="Y";;
  228.     inp) printf "IP firewall input rules, default policy: " 
  229. get_policy input
  230. ;;
  231.     out) printf "IP firewall output rules, default policy: " 
  232. get_policy output
  233. ;;
  234.     fwd) printf "IP firewall forward rules, default policy: " 
  235. get_policy forward
  236. ;;
  237.     *) barf "Unknown chain for list_chain - `$1'"
  238. ;;
  239.     esac
  240.     if [ -n "$2" -o -n "$IS_ACCT" ]
  241.     then
  242. if [ -z "$4" ]
  243. then
  244.     printf "%5s " pkts
  245.     printf "%5s " bytes
  246. else
  247.     printf "%8s " pkts
  248.     printf "%10s " bytes
  249. fi
  250.     fi
  251. # if (!(format & FMT_NOKIND)) {
  252. #  if (chain == CHN_ACCT)
  253. #  fprintf(fp, FMT("%-3s ","%s "), "dir");
  254. #  else
  255. #  fprintf(fp, FMT("%-5s ","%s "), "type");
  256. # }
  257.     case "$1" in
  258.     acct*) printf "%-3s " dir ;;
  259.     *) printf "%-5s " type ;;
  260.     esac
  261. # fputs("prot ", fp);
  262.     printf "prot "
  263. # if (format & FMT_OPTIONS)
  264. #  fputs("opt  ", fp);
  265. # if (format & FMT_TOS)
  266. #  fputs("tosa tosx ", fp);
  267. # if (format & FMT_VIA) {
  268. #  fprintf(fp, FMT("%-7s ","(%s "), "ifname");
  269. #  fprintf(fp, FMT("%-15s ","%s) "), "ifaddress");
  270. # }
  271.     if [ -n "$2" ]
  272.     then
  273. printf "opt  tosa tosx %-7s %-15s " ifname ifaddress
  274.     fi
  275. # fprintf(fp, FMT("%-20s ","%s "), "source");
  276. # fprintf(fp, FMT("%-20s ","%s "), "destination");
  277. # fputs("portsn", fp);
  278. # }
  279.     printf "%-20s %-20s ports" source destination
  280.     echo
  281.     case "$1" in
  282. acct*) shift;
  283. (list_chain_real acctin "$@" "1" "1"
  284.  list_chain_real acctout "$@" "1" "1" 
  285.  list_chain_real acctboth "$@" "1" "1") | sort -n | cut -c11-;;
  286. *) list_chain_real "$@" ;;
  287.     esac
  288. }
  289. list_chain_real() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS $PRINT_COUNTS $PREPEND_MARK
  290. {
  291.     CHAIN="$1"
  292.     LIST_VERBOSE="$2"
  293.     NUMERIC="$3"
  294.     EXPAND_NUMBERS="$4"
  295.     PRINT_COUNTS="$5"
  296.     PREPEND_MARK="$6"
  297.     # The ipfwadm code looks like: (* = -e only)
  298.     # *    *               *    *    *    *    *       
  299.     # pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR
  300.     #
  301.     # The ipchains code looks like: (* = -v only)
  302.     # *    *               *    *    *    *    *       
  303.     # pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
  304.     LAST_MARK=xxx
  305.     BIDIR=0
  306.     SYN_NO_PROTO=0
  307.     SRCPORTS=""
  308.     DSTPORTS=""
  309.     [ -z "$NUMERIC" ] || NUMERIC="-n"
  310.     $IPCHAINS -L $CHAIN -v -x $NUMERIC | tail +3 |
  311.     while true
  312.     do
  313. if ! read PCNT BCNT TARG PROTO FLAGS TOSA TOSX IFNM MARK SRCIP DSTIP SRCPTS IGN1 DSTPTS REDIR
  314. then
  315.     # Dump last rule.
  316.     if [ "$LAST_MARK" != "xxx" ] 
  317.     then
  318. [ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK"
  319. 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"
  320.     fi
  321.     return
  322. fi
  323. [ -z "$DEBUG_IPFWADM" ] || echo RULE is "$PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX "$IFNM" $MARK $SRCIP $DSTIP $SRCPTS $IGN1 $DSTPTS $REDIR" 1>&2
  324. if [ "$LAST_MARK" = "$MARK" ]
  325. then
  326. # Fold rules back together.
  327. # We combine for any of the following reasons:
  328. # -k or -y used with no protocol: first rule has proto TCP and 'y'.
  329. # -b used: SRC & DST reversed.
  330. # Multiple ports: all the same but for port.
  331. # Worst cases:
  332. # ipfwadm -I -a accept -b -P tcp -S 0/0 1 4 -D 1/1 5 9
  333. # => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
  334. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 1       5
  335. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 5       1
  336. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 1       9
  337. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 9       1
  338. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 4       5
  339. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 5       4
  340. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    0/0 1/1 4       9
  341. #    ?    ?    ?    TCP   ?    ?    ?    ?    ?    1/1 0/0 9       4
  342. #
  343. # ipfwadm -I -a accept -b -y -S 0/0 -D 1/1
  344. # => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
  345. #    ?    ?    ?    TCP   ?y?? ?    ?    ?    ?    0/0 1/1
  346. #    ?    ?    ?    TCP   ?y?? ?    ?    ?    ?    1/1 0/0
  347. #    ?    ?    ?    ANY   ?-?? ?    ?    ?    ?    0/0 1/1
  348. #    ?    ?    ?    ANY   ?-?? ?    ?    ?    ?    1/1 0/0
  349. #      if [ -n "$DEBUG_IPFWADM" ]
  350. #      then
  351. # echo LAST_PROTO = `"$LAST_PROTO"'
  352. # echo PROTO = `"$PROTO"'
  353. #  echo LAST_SRCIP = `"$LAST_SRCIP"'
  354. #  echo DSTIP = `"$DSTIP"'
  355. #  echo LAST_DSTIP = `"$LAST_DSTIP"'
  356. #  echo SRCIP = `"$SRCIP"'
  357. #  echo LAST_SRCPTS = `"$LAST_SRCPTS"'
  358. #  echo DSTPTS = `"$DSTPTS"'
  359. #  echo LAST_DSTPTS = `"$LAST_DSTPTS"'
  360. #  echo SRCPTS = `"$SRCPTS"'
  361. #      fi
  362.     if [ "$LAST_PROTO" = !tcp -a "$PROTO" = tcp ]
  363.     then
  364. [ -n "$DEBUG_IPFWADM" ] && echo "Found SYN rule."
  365. SYN_NO_PROTO=1
  366. PCNT=$(($LAST_PCNT + $PCNT))
  367. BCNT=$(($LAST_BCNT + $BCNT))
  368. PROTO="all"
  369.     elif [ "$LAST_SRCIP" = "$DSTIP" -a "$LAST_DSTIP" = "$SRCIP" -a "$LAST_SRCPTS" = "$DSTPTS" -a "$LAST_DSTPTS" = "$SRCPTS" ]
  370.     then
  371. [ -n "$DEBUG_IPFWADM" ] && echo "Found bidir rule."
  372. BIDIR=1
  373. LAST_PCNT=$(($LAST_PCNT + $PCNT))
  374. LAST_BCNT=$(($LAST_BCNT + $BCNT))
  375. # Don't transfer this rule to LAST_ vars - effectively ignore.
  376. continue;
  377.     else
  378. [ -n "$DEBUG_IPFWADM" ] && echo "Found port rule."
  379. # For n source ports and m dest ports, there will be
  380. # n x m rules.  So, we add to SRCPORTS when we see a new
  381. # SRCPTS, but only add to DSTPORTS for the first SRCPORTS.
  382. if [ "$SRCPTS" != "$LAST_SRCPTS" ]
  383. then
  384.     SRCPORTS="$SRCPORTS $SRCPTS"
  385. fi
  386. if [ "$SRCPORTS" = "$SRCPTS" ]
  387. then
  388.     DSTPORTS="$DSTPORTS $DSTPTS"
  389. fi
  390. PCNT=$(($LAST_PCNT + $PCNT))
  391. BCNT=$(($LAST_BCNT + $BCNT))
  392.     fi
  393. else
  394.     # Dump last rule.
  395.     if [ "$LAST_MARK" != "xxx" ]
  396.     then
  397. [ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK"
  398. 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"
  399.     fi
  400.     BIDIR=0
  401.     SYN_NO_PROTO=0
  402.     SRCPORTS="$SRCPTS"
  403.     DSTPORTS="$DSTPTS"
  404. fi
  405. # Save for next iteration, in case mark the same.
  406. LAST_PCNT=$PCNT
  407. LAST_BCNT=$BCNT
  408. LAST_PROTO=$PROTO
  409. LAST_FLAGS=$FLAGS
  410. LAST_TOSA=$TOSA
  411. LAST_TOSX=$TOSX
  412. LAST_IFNM="$IFNM"
  413. LAST_MARK=$MARK
  414. LAST_SRCIP=$SRCIP
  415. LAST_DSTIP=$DSTIP
  416. LAST_REDIR="$REDIR"
  417. LAST_SRCPTS="$SRCPTS"
  418. LAST_DSTPTS="$DSTPTS"
  419. case "$CHAIN" in
  420. acctin) LAST_TARG=in ;;
  421. acctout) LAST_TARG=out ;;
  422. acctboth) LAST_TART=i/o ;;
  423. *)
  424.     case "$TARG" in
  425.     REDIRECT) LAST_TARG="acc/r" ;;
  426.     MASQ) LAST_TARG="acc/m" ;;
  427.     ACCEPT) LAST_TARG="acc" ;;
  428.     REJECT) LAST_TARG="rej" ;;
  429.     DENY) LAST_TARG="deny" ;;
  430.     *) barf Unknown target `"$TARG"'. ;;
  431.     esac
  432.     ;;
  433. esac
  434.     done
  435. }
  436. ############################################################################
  437. if [ ! -f $PROC_FIREWALL_NAMES ]
  438. then
  439.     if [ -f /proc/net/ip_input -o -f /proc/net/ip_acct ]
  440.     then
  441. # Old kernel.  Let's play nice.
  442. [ -x /sbin/ipfwadm.real ] && exec /sbin/ipfwadm.real "$@" 
  443.     fi
  444.     echo "Generic IP Firewall Chains not in this kernel" 1>&2
  445.     exit 1
  446. fi
  447. while [ $# != 0 ]
  448. do
  449.     case "$1" in
  450.     -A)
  451. case x"$2" in
  452. x-*) CHAIN=acctboth ;;
  453. xboth) CHAIN=acctboth; shift ;;
  454. xin) CHAIN=acctin; shift ;;
  455. xout) CHAIN=acctout; shift ;;
  456. x) CHAIN=acctboth ;;
  457.   *) barf Unknown option `"$2"' ;;
  458. esac
  459. ;;
  460.     -I)
  461. CHAIN=inp
  462. ;;
  463.     -O)
  464. CHAIN=out
  465. ;;
  466.     -F)
  467. CHAIN=fwd
  468. ;;
  469.     -M)
  470. MASQ_MODE=1
  471. ;;
  472.     -a)
  473. COMMAND=-A
  474. case x"$2" in
  475. x-*) TARGET="" ;;
  476. x) TARGET="" ;;
  477. xr*) TARGET=REJECT; shift ;;
  478. xd*) TARGET=DENY; shift ;;
  479. xa*) TARGET=ACCEPT; shift ;;
  480. xm*) TARGET=ACCEPT; MASQ=1; shift ;;
  481.   *) barf Unknown policy for append: `"$2"' ;;
  482. esac
  483. ;;
  484.     -i)
  485. COMMAND="-I "
  486. case x"$2" in
  487. x-*) TARGET="" ;;
  488. x) TARGET="" ;;
  489. xr*) TARGET=REJECT; shift ;;
  490. xd*) TARGET=DENY; shift ;;
  491. xa*) TARGET=ACCEPT; shift ;;
  492.   *) barf Unknown policy for insert: `"$2"' ;;
  493. esac
  494. ;;
  495.     -d)
  496. COMMAND=-D
  497. case x"$2" in
  498. x-*) TARGET="" ;;
  499. x) TARGET="" ;;
  500. xr*) TARGET=REJECT; shift ;;
  501. xd*) TARGET=DENY; shift ;;
  502. xa*) TARGET=ACCEPT; shift ;;
  503.   *) barf Unknown policy for delete: `"$2"' ;;
  504. esac
  505. ;;
  506.     -l)
  507. LIST=1
  508. ;;
  509.     -z)
  510. COMMAND=-Z
  511. ;;
  512.     -f)
  513. COMMAND=-F
  514. ;;
  515.     -p)
  516. COMMAND=-P
  517. case "$2" in
  518. r*) TARGET=REJECT; shift ;;
  519. d*) TARGET=DENY; shift ;;
  520. a*) TARGET=ACCEPT; shift ;;
  521. m*) TARGET=MASQ; shift ;;
  522.   *) barf Unknown policy for -p: `"$2"' ;;
  523. esac
  524. ;;
  525.     -s)
  526. COMMAND=-S
  527. OPTIONS="$2 $3 $4"
  528. shift 3
  529. ;;
  530.     -c)
  531. COMMAND=-C
  532. ;;
  533.     -h)
  534. print_help
  535. ;;
  536.     -P)
  537. PROTOCOL="-p $2"
  538. shift
  539. ;;
  540.     -S)
  541. SRC_OPTIONS="-s $2"
  542. shift
  543. while true
  544. do
  545.     case x"$2" in
  546. x) break ;;
  547. x-*) break ;;
  548. x?*) SRC_PORTS="$2 $SRC_PORTS" ;;
  549.     esac
  550.     shift
  551. done
  552. ;;
  553.     -D)
  554. DST_OPTIONS="-d $2"
  555. shift
  556. while true
  557. do
  558.     case x"$2" in
  559. x) break ;;
  560. x-*) break ;;
  561. x?*) DST_PORTS="$2 $DST_PORTS" ;;
  562.     esac
  563.     shift
  564. done
  565. ;;
  566.     -V)
  567. VIA_ADDR="$2"
  568. shift
  569. ;;
  570.     -W)
  571. INTERFACE="$2"
  572. OPTIONS="$OPTIONS -i $2"
  573. shift
  574. ;;
  575.     -b)
  576. OPTIONS="$OPTIONS -b"
  577. ;;
  578.     -e)
  579. LIST_VERBOSE=1
  580. ;;
  581.     -k)
  582. TCPSYN="! -y"
  583. ;;
  584.     -m)
  585. MASQ=1
  586. ;;
  587.     -n)
  588. NUMERIC=1
  589. ;;
  590.     -o)
  591. OPTIONS="$OPTIONS -l"
  592. ;;
  593.     -r)
  594. case x"$2" in
  595.     x-*) REDIR=0 ;;
  596.     x) REDIR=0 ;;
  597.     x?*) REDIR="$2"; shift ;;
  598. esac
  599. ;;
  600.     -t)
  601. TOSAND=$(($2 | 0x01))
  602. TOSXOR=$(($3 & 0xFE))
  603. OPTIONS="$OPTIONS -t "`printf "0x%02x 0x%02x" $TOSAND $TOSXOR`
  604. shift 2
  605. ;;
  606.     -v)
  607. OPTIONS="$OPTIONS -v"
  608. ;;
  609.     -x)
  610. EXPAND_NUMBERS=1;
  611. ;;
  612.     -y)
  613. TCPSYN="-y"
  614. ;;
  615.     --version)
  616. echo "ipfwadm wrapper version 1.1.2"
  617. exit 0
  618. ;;
  619.     -??*)
  620. echo "ERROR: Please separate arguments, eg `-Mle' => `-M -l -e'." >&2
  621. exit 1
  622. ;;
  623.     *) barf Unexpected argument `"$1"'.
  624. ;;
  625.     esac
  626.     shift
  627. done
  628. # Variables to worry about:
  629. #  $CHAIN - actual chain to work on.
  630. # X$MASQ_MODE - set if -M given.
  631. # X$COMMAND - set if this is a simple command conversion.
  632. # X$TARGET - set for COMMAND of -A, -I, -D or -P (but see REDIR and MASQ).
  633. # X$LIST - set if they want a list.
  634. # X$NUMERIC - list with -n.
  635. # X$LIST_VERBOSE - list all info.
  636. # X$EXPAND_NUMBERS - list full numbers.
  637. # X$OPTIONS - miscellaneous easy-to-convert options.
  638. # X$SRC_OPTIONS - set if a source address is specified.
  639. # X$SRC_PORTS - space-separated list of specified source ports/ranges.
  640. # X$DST_OPTIONS - set if a dest address is specified.
  641. # X$DST_PORTS - space-separated list of specified dest ports/ranges.
  642. #  $VIA_ADDR - an interface address if one is specified.
  643. #  $INTERFACE - an interface name if one is specified.
  644. # X$TCPSYN - set if `-k' or `-y' is specified.
  645. # X$MASQ - set if `-m' is specified.
  646. # X$REDIR - set to the port if `-r port' is specified
  647. if [ -n "$MASQ_MODE" ]
  648. then
  649.     if [ -n "$LIST" ]
  650.     then
  651. $IPCHAINS -M -L $OPTIONS
  652.     else
  653. $IPCHAINS $COMMAND $OPTIONS
  654.     fi
  655. elif [ -n "$LIST" ]
  656. then
  657.     if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES
  658.     then
  659. echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2
  660. exit 0
  661.     fi
  662.     # Construct a list.
  663.     if [ x$COMMAND = x-Z ]
  664.     then
  665. # We have to atomically zero and list a chain.  This is
  666. # currently impossible, so we:
  667. # 1) stop all packets on the given chain. 
  668. # 2) list the values.
  669. # 3) clear the counters.
  670. # 4) resume on the given chain.
  671. case "$CHAIN" in
  672.     acct*)
  673. $IPCHAINS -I 1 input -j DENY
  674. $IPCHAINS -I 1 output -j DENY
  675. ;;
  676.     inp)
  677. $IPCHAINS -I 1 input -j DENY
  678. ;;
  679.     out)
  680. $IPCHAINS -I 1 output -j DENY
  681. ;;
  682.     fwd)
  683. $IPCHAINS -I 1 forward -j DENY
  684. ;;
  685.     *) barf Unknown chain to stop: `"$CHAIN"'.
  686. esac
  687. list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS"
  688. $IPFWADM -Z $CHAIN
  689. case "$CHAIN" in
  690.     acct*)
  691. $IPCHAINS -D 1 input
  692. $IPCHAINS -D 1 output
  693. ;;
  694.     inp)
  695. $IPCHAINS -D 1 input
  696. ;;
  697.     out)
  698. $IPCHAINS -D 1 output
  699. ;;
  700.     fwd)
  701. $IPCHAINS -D 1 forward
  702. ;;
  703.     *) barf Unknown chain to restart: `"$CHAIN"'.
  704. esac
  705.     else
  706. list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS"
  707.     fi
  708. elif [ x"$COMMAND" = x"-F" -o x"$COMMAND" = x"-Z" -o x"$COMMAND" = x"-C" ]
  709. then
  710.     if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES
  711.     then
  712. echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2
  713. exit 0
  714.     fi
  715.     if [ "$CHAIN" = acctboth ]
  716.     then
  717. # Do it to all of them.
  718. $IPCHAINS $COMMAND acctin $OPTIONS
  719. $IPCHAINS $COMMAND acctout $OPTIONS
  720.     fi
  721.     $IPCHAINS $COMMAND $CHAIN $OPTIONS
  722. else
  723.     grep -q IpFwAdM! < $PROC_FIREWALL_NAMES || setup_chains
  724.     # Figure out what the target should be.
  725.     if [ -n "$REDIR" ]
  726.     then
  727. TARGET="REDIRECT $REDIR"
  728.     elif [ -n "$MASQ" ]
  729.     then
  730. TARGET=MASQ
  731.     fi
  732.     if [ x"$COMMAND" = x"-P" ]
  733.     then
  734. case "$CHAIN" in
  735. inp) CHAIN=input ;;
  736. out) CHAIN=output ;;
  737. fwd) CHAIN=forward ;;
  738. *) barf Illegal chain for -P: `"$CHAIN"'.;;
  739. esac
  740. $IPCHAINS $COMMAND $CHAIN $TARGET $OPTIONS
  741.     else
  742. # If they used -V, and not -W, then try to figure out interface
  743. # name.  ALWAYS warn about difference.
  744. if [ -n "$VIA_ADDR" ]
  745. then
  746.     if [ -n "$INTERFACE" ]
  747.     then
  748. echo Warning: `-V $VIA_ADDR' option ignored; using `-W $INTERFACE' only.
  749.     else
  750. INTERFACE=`ifconfig | awk -v ADDR=$VIA_ADDR '/^[a-z0-9A-Z]/ { IFNAME=$1 } $0 ~ "^[^A-Za-z0-9:]*inet addr:" ADDR { print IFNAME}'`
  751. if [ -z "$INTERFACE" ]
  752. then
  753.     echo Can't handle -V option: can't find interface name for the address `$VIA_ADDR'. 1>&2
  754.     echo Please replace the -V with the appropriate -W option. 1>&2
  755.     exit 1
  756. fi
  757. echo Replacing `-V $VIA_ADDR' with `-W $INTERFACE'.
  758. OPTIONS="$OPTIONS -i $INTERFACE"
  759.     fi
  760. fi
  761. # Insert, append or delete.
  762. case $COMMAND in
  763.     # For Insert, get (and decrement) minimal mark #.
  764.     -I*) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -3 | tail -1); echo $9)
  765. $IPCHAINS -R $SPECIAL_CHAIN 1 -m $(($MARK - 1))
  766. MARK="-m $MARK"
  767. ;;
  768.     # For Append, get (and increment) maximum mark #.
  769.     -A) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -4 | tail -1); echo $9)
  770. $IPCHAINS -R $SPECIAL_CHAIN 2 -m $(($MARK + 1))
  771. MARK="-m $MARK"
  772. ;;
  773. esac
  774. # Only care about TCP SYN if -p TCP not specified.
  775. if [ -n "$TCPSYN" ]
  776. then
  777.     case "$PROTOCOL" in
  778. *[Tt][Cc][Pp]) 
  779.     OPTIONS="$OPTIONS $PROTOCOL $TCPSYN"
  780.     TCPSYN=""
  781. ;;
  782.     esac
  783. else
  784.     OPTIONS="$OPTIONS $PROTOCOL"
  785. fi
  786. # Mangle source port and dest port args.
  787. if [ -z "$SRC_PORTS" ]; then SRC_PORTS="X"; fi
  788. if [ -z "$DST_PORTS" ]; then DST_PORTS="X"; fi
  789. [ -n "$TARGET" ] && TARGET="-j $TARGET"
  790. for SRC in $SRC_PORTS
  791. do
  792.     if [ $SRC = "X" ]; then SRC=""; fi
  793.     for DST in $DST_PORTS
  794.     do
  795. if [ $DST = "X" ]; then DST=""; fi
  796. if [ -n "$TCPSYN" ]
  797. then
  798.     $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS -p ! tcp $TARGET $MARK || barf "ipchains failed!"
  799.     $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS -p tcp $TCPSYN $TARGET $MARK  || barf "ipchains failed!"
  800. else
  801.     $IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS $TARGET $MARK || barf "ipchains failed!"
  802. fi
  803.     done
  804. done
  805.     fi
  806. fi