#!/bin/bash
#
# License:  GNU General Public License version 3 or newer
# Author:   Johannes Hubertz <johannes@hubertz.de>
# Version:  0.9.10
# Date:     2014-09-01
#
# Fullname: /usr/sbin/iptables-optimizer
#
# 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 paket/byte counters
#          for easier long term debugging
#
#    -h    hint for options
#
#    -i    verbose logging reduced to INPUT and OUTPUT chains
#
#    -v    turns on logging, twice is more verbose
#
##############################################################
# 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="opti"
#
# $AUTO points to new file containing new ruleset
AUTO__DIR=/var/cache/iptables-optimizer
AUTO_FILE=auto-apply
AUTO=${AUTO__DIR}/${AUTO_FILE}
#
# all files are 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
#
INOUT=$FALSE
#
source iptables-optimizer-functions
#
###############################################
#
# stop on first error, respect errors in pipes
set -e
set -o pipefail
#
# 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
log_start
#
# look if new rules are present and do neccessary actions
check_auto_apply_ready "${AUTO}" && auto_apply_execute "${AUTO}"
#
cd $WORKBENCH
#
save_the_tables iptables-optimizer-save-output iptables-optimizer-save-errors
#
run_python_part iptables-optimizer-save-output iptables-optimizer-output iptables-optimizer-partitions $INOUT
#
load_the_tables iptables-optimizer-output iptables-optimizer-restore-out iptables-optimizer-restore-err $COUNTER
#
exit 0
# EoF
