# The plugin configuration file
###############################
PLUGIN_CONF_FILE="dyndns-host-open.conf"

# Preinit return value for success
PLUGIN_RET_VAL=0

# Check sanity of environment
dyndns_host_open_helper_sanity_check()
{
  if [ -z "$DYNDNS_HOST_OPEN_TCP" -a -z "$DYNDNS_HOST_OPEN_UDP" -a \
       -z "$DYNDNS_HOST_OPEN_IP"  -a -z "$DYNDNS_HOST_OPEN_ICMP" ]; then
    echo "** ERROR: The plugin config file is not (properly) setup!" >&2
    return 1
  fi

  # Check whether chain exists
  if ! ip4tables -nL DYNDNS_CHAIN >/dev/null 2>&1; then
    echo "** ERROR: DYNDNS_CHAIN does not exist! **" >&2
    return 1
  fi

  # Check if chain is inserted in the main chains
#  if ! ip4tables -nL EXT_INPUT_CHAIN |grep -q '^DYNDNS_CHAIN '; then
#    echo "** ERROR: DYNDNS_CHAIN is not inserted in the EXT_INPUT_CHAIN chain! **" >&2
#    return 1
#  fi

  return 0
}


dyndns_host_open_helper_do_work()
{
  local RETVAL=0

  # Flush the DYNDNS_CHAIN
  iptables -F DYNDNS_CHAIN

  # Add TCP ports to allow for certain hosts
  ##########################################
  unset IFS
  for rule in $DYNDNS_HOST_OPEN_TCP; do
    if parse_rule "$rule" DYNDNS_HOST_OPEN_TCP "interfaces-destips-hosts-ports"; then
      echo "${INDENT}$(show_if_ip "$interfaces" "$destips")Allowing $hosts for TCP port(s): $ports"

      IFS=' ,'
      for host in $hosts; do
        # get_dynamic_host_cached returns hostname in $host_ip
        if ! get_dynamic_host_cached $host || [ -z "$host_ip" ]; then
          echo "** WARNING: Skipping TCP rule(s) for \"$host\"! **" >&2
          RETVAL=1
          continue
        fi

        for interface in $interfaces; do
          for host_ip2 in $host_ip; do
            for destip in $destips; do
              for port in $ports; do
                iptables -A DYNDNS_CHAIN $(ipt_if -i "$interface") -s $host_ip2 -d $destip -p tcp --dport $port -j ACCEPT
              done
            done
          done
        done
      done
    fi
  done

  # Add UDP ports to allow for certain hosts
  ##########################################
  unset IFS
  for rule in $DYNDNS_HOST_OPEN_UDP; do
    if parse_rule "$rule" DYNDNS_HOST_OPEN_UDP "interfaces-destips-hosts-ports"; then
      echo "${INDENT}$(show_if_ip "$interfaces" "$destips")Allowing $hosts for UDP port(s): $ports"

      IFS=' ,'
      for host in $hosts; do
        # get_dynamic_host_cached returns hostname in $host_ip
        if ! get_dynamic_host_cached $host || [ -z "$host_ip" ]; then
          echo "** WARNING: Skipping UDP rule(s) for \"$host\"! **" >&2
          RETVAL=1
          continue
        fi

        for interface in $interfaces; do
          for host_ip2 in $host_ip; do
            for destip in $destips; do
              for port in $ports; do
                iptables -A DYNDNS_CHAIN $(ipt_if -i "$interface") -s $host_ip2 -d $destip -p udp --dport $port -j ACCEPT
              done
            done
          done
        done
      done
    fi
  done

  # Add IP protocols to allow for certain hosts
  #############################################
  unset IFS
  for rule in $DYNDNS_HOST_OPEN_IP; do
    if parse_rule "$rule" DYNDNS_HOST_OPEN_IP "interfaces-destips-hosts-protos"; then
      echo "${INDENT}$(show_if_ip "$interfaces" "$destips")Allowing $hosts for IP protocol(s): $protos"

      IFS=' ,'
      for host in $hosts; do
        # get_dynamic_host_cached returns hostname in $host_ip
        if ! get_dynamic_host_cached $host || [ -z "$host_ip" ]; then
          echo "** WARNING: Skipping IP rule(s) for \"$host\"! **" >&2
          RETVAL=1
          continue
        fi

        for interface in $interfaces; do
          for host_ip2 in $host_ip; do
            for destip in $destips; do
              for proto in $protos; do
                iptables -A DYNDNS_CHAIN $(ipt_if -i "$interface") -s $host_ip2 -d $destip -p $proto -j ACCEPT
              done
            done
          done
        done
      done
    fi
  done

  # Add ICMP to allow for certain hosts
  #####################################
  unset IFS
  for rule in $DYNDNS_HOST_OPEN_ICMP; do
    if parse_rule "$rule" DYNDNS_HOST_OPEN_ICMP "interfaces-destips-hosts"; then
      echo "${INDENT}$(show_if_ip "$interfaces" "$destips")Allowing $hosts for ICMP-requests(ping)"

      IFS=' ,'
      for host in $hosts; do
        # get_dynamic_host_cached returns hostname in $host_ip
        if ! get_dynamic_host_cached $host || [ -z "$host_ip" ]; then
          echo "** WARNING: Skipping ICMP rule(s) for \"$host\"! **" >&2
          RETVAL=1
          continue
        fi

        for interface in $interfaces; do
          for host_ip2 in $host_ip; do
            for destip in $destips; do
              iptables -A DYNDNS_CHAIN $(ipt_if -i "$interface") -s $host_ip2 -d $destip -p icmp --icmp-type echo-request -j ACCEPT
            done
          done
        done
      done
    fi
  done

  return $RETVAL
}


############
# Mainline #
############

# Check where to find the config file
CONF_FILE=""
if [ -n "$PLUGIN_CONF_PATH" ]; then
  CONF_FILE="$PLUGIN_CONF_PATH/$PLUGIN_CONF_FILE"
fi

# Check if the config file exists
if [ ! -f "$CONF_FILE" ]; then
  echo "** ERROR: Config file \"$CONF_FILE\" not found! **" >&2
  PLUGIN_RET_VAL=1
else
  # Source the plugin config file
  . "$CONF_FILE"

  # Only proceed if environment ok
  if ! dyndns_host_open_helper_sanity_check; then
    PLUGIN_RET_VAL=1
  else
    # Parse rules
    if ! dyndns_host_open_helper_do_work; then
      PLUGIN_RET_VAL=1
    fi
  fi
fi
