#!/bin/sh

MOD_NAME=loopback
MOD_DEFAULTS=/opt/$MOD_NAME/etc/defaults
MOD_SETTINGS=/opt/$MOD_NAME/etc/settings
CFG_MAX_LOOPBACK=4
CHAIN_PRE=mod_pre_$MOD_NAME
CHAIN_POST=mod_post_$MOD_NAME
CHAIN_MARK=mod_mark_$MOD_NAME
MARK_PREFIX=0x23002

[ -f "$MOD_SETTINGS" ] || cp $MOD_DEFAULTS $MOD_SETTINGS
. $MOD_SETTINGS

case "$1" in
  start)
    echo "Starting module $MOD_NAME:"
    if [ "$MOD_LOOPBACK_ENABLED" != "1" ]; then
      echo "skipped"
      exit 0
    fi
    iptables -t nat -N $CHAIN_PRE
    iptables -t nat -A pre_mod -j $CHAIN_PRE
    iptables -t nat -N $CHAIN_POST
    iptables -t nat -I post -j $CHAIN_POST
    iptables -t mangle -N $CHAIN_MARK
    iptables -t mangle -I OUTPUT -j $CHAIN_MARK
    i=1
    while [ "$i" -le "$CFG_MAX_LOOPBACK" ]; do
      eval ipaddr='$MOD_LOOPBACK_'$i'_IPADDR'
      eval permit_addr='$MOD_LOOPBACK_'$i'_PERMIT_IPADDR'
      eval permit_mask='$MOD_LOOPBACK_'$i'_PERMIT_MASK'
      [ -z "$permit_mask" ] && permit_mask='255.255.255.255'
      if [ -n "$ipaddr" ]; then
        if [ -z "$permit_addr" ]; then
          iptables -t nat -A $CHAIN_PRE -d $ipaddr -j REDIRECT &>/dev/null
        else
          iptables -t nat -A $CHAIN_PRE -s $permit_addr/$permit_mask -d $ipaddr -j REDIRECT &>/dev/null
          iptables -t mangle -A $CHAIN_MARK -d $permit_addr/$permit_mask -j MARK --set-mark "$MARK_PREFIX$i" &>/dev/null
          iptables -t nat -A $CHAIN_POST -m mark --mark "$MARK_PREFIX$i" -j SNAT --to-source $ipaddr &>/dev/null
        fi
      fi
      i=$((i + 1))
    done
    echo "done"
    exit 0
    ;;
  stop)
    echo "Stopping module $MOD_NAME:"
    iptables -t nat -D pre_mod -j $CHAIN_PRE &>/dev/null
    iptables -t nat -F $CHAIN_PRE &>/dev/null
    iptables -t nat -X $CHAIN_PRE &>/dev/null
    iptables -t nat -D post -j $CHAIN_POST &>/dev/null
    iptables -t nat -F $CHAIN_POST &>/dev/null
    iptables -t nat -X $CHAIN_POST &>/dev/null
    iptables -t mangle -D OUTPUT -j $CHAIN_MARK &>/dev/null
    iptables -t mangle -F $CHAIN_MARK &>/dev/null
    iptables -t mangle -X $CHAIN_MARK &>/dev/null
    i=1
    while [ "$i" -le "$CFG_MAX_LOOPBACK" ]; do
      eval ipaddr='$MOD_LOOPBACK_'$i'_IPADDR'
      eval permit_addr='$MOD_LOOPBACK_'$i'_PERMIT_IPADDR'
      [ -n "$ipaddr" ] && conntrack -D -d $ipaddr &>/dev/null
      [ -n "$permit_addr" ] && conntrack -D -n $ipaddr &>/dev/null
      i=$((i + 1))
    done
    echo "done"
    exit 0
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  status)
    [ "$MOD_LOOPBACK_ENABLED" == "1" ] && echo "Module $MOD_NAME is running"
    [ "$MOD_LOOPBACK_ENABLED" != "1" ] && echo "Module $MOD_NAME is not running"
    exit 0
    ;;
  defaults)
    cd /opt/$MOD_NAME/etc && cp defaults settings
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|status|defaults}"
    exit 1
esac
