#!/bin/bash
#
# License:  GNU General Public License version 3 or newer
# Author:   Johannes Hubertz <johannes@hubertz.de>
# Version:  0.9.13
# Date:     2015-02-10
#
# Fullname: /usr/sbin/iptables-optimizer
#           /usr/sbin/ip6tables-optimizer  (works a symlink)
#
# optional command line switches:
#    -a    suppress checking and applying of new rulesets
#          think twice because of concurrent iptables-commands
#          usually are not a very good idea!
#
#    -c    if present, no resetting the packet/byte counters
#          for easier long term debugging
#
#    -h    hint for options
#
#    -v    turns on logging, twice is more verbose
#
#    -w    verbose logging reduced to INPUT and OUTPUT chains
#
##############################################################
# iptables-optimizer runs in discrete steps:
#
# 0: if auto-apply is present, do it
#    done with shell commands
#
# 1: get iptables out of the kernel into file
#    done with shell commands
#
# 2: sort this file due to the counters into another file
#    done with pythonic intelligence
#
# 3: feed the second files iptables into the kernel
#    done with shell commands
#
# Almost every function was moved into another file, which is
# sourced here. Simple reason for that is to enable the fine
# tests with shunit2. All the tests for the shell and the
# python part are included in the debian source package.
#
# Have fun!
##############################################################
#
# functions, files and paths are defined here
#
# first, no surprises by any language wanted
export LANG=C
#
TRUE=0
FALSE=1
#
#
# NAME is for logging, the shorter the better!
NAME="opti4"
#
# check if iptables or ip6tables, magic for the executables
IP6=""
[ `basename $0` == "ip6tables-optimizer" ] && IP6="6" && NAME="opti6"
# IP6 now used wherever possible to keep the two sourcecodes in sync
#
# $AUTO points to new file containing new ruleset, 
#       which comes from outside the iptables-optimizer
AUTO__DIR=/var/cache/iptables-optimizer
AUTO_FILE=auto-apply${IP6}
AUTO=${AUTO__DIR}/${AUTO_FILE}
#
# all iptables-optimizer internal files reside here
WORKBENCH=/var/run
#
# and yes, we want logging, less or verbose
LOG="/usr/bin/logger -t $NAME -p user.warn "
#
# command line argument -c manipulates the variable
COUNTER=0
# 0 => do reset packet/byte counters on the restore, default
# 1 => do not reset packet/byte counters on restore
#
# command line argument -v manipulates the variable,
#         may be used more than once
VERBLOG=0
# if 0, smallest logging, this is default
# if 1, steps are logged
# if 2, partition details are logged as well
#
# logging only for INPUT/OUTPUT or take all chains as default 
INOUT=$FALSE
#
# for -e switch and possible erroneous exits, always have be prepared
ERROR_TEXT="starting up"
#
# take all the neccessary functions from file
source iptables-optimizer-functions
#
###############################################
#
# stop on first error, respect errors in pipes
set -e
set -o pipefail
set -o errtrace
trap error_func ERR
#
# evaluate command line arguments
#
while getopts ":achvw" opt; do
  case $opt in
    a) AUTO=${AUTO__DIR}/unwanted ;;
    c) COUNTER=1;;
    h) usage; exit 1;;
    v) VERBLOG=$(( ${VERBLOG} + 1 ));;
    w) INOUT=$TRUE; VERBLOG=2;;
    \?) echo "invalid option -- $OPTARG" >&2 ; usage; exit 1;;
  esac
done
###############################################
#
# start the job here
ERROR_TEXT="started up"
log_start
#
# look if new rules are present and do neccessary actions
ERROR_TEXT="checking ${AUTO}"
check_auto_apply_ready "${AUTO}" && auto_apply_execute "${AUTO}"
#
cd $WORKBENCH
#
ERROR_TEXT="storing tables"
save_the_tables ip${IP6}tables-optimizer-save-output ip${IP6}tables-optimizer-save-errors
#
ERROR_TEXT="running pythonic part"
run_python_part ip${IP6}tables-optimizer-save-output ip${IP6}tables-optimizer-output ip${IP6}tables-optimizer-partitions $INOUT
#
ERROR_TEXT="restoring tables"
load_the_tables ip${IP6}tables-optimizer-output ip${IP6}tables-optimizer-restore-out ip${IP6}tables-optimizer-restore-err $COUNTER
#
exit 0
# EoF
