#!/bin/sh

. /lib/functions.sh

process_port_trigger() {
	local rule_id="$1"
	local is_enabled=""
	local duration=""
	local trigger_dport=""
	local trigger_dport_end=""
	local protocol=""
	local interface=""
	local open_dport=""
	local open_dport_end=""
	local open_protocol=""
	local ptg_id=""
	local IP_RULE=""
	local IP6_RULE=""
	local IP_RULE_FWD=""

	get_port_trigger() {
		local ptg_name
		config_get ptg_name "$1" "name"
		if [ "$ptg_name" == "$2" ]; then
			ptg_id="$1"
			return
		fi
	}

	ptg_id=""
	config_get name "$rule_id" "port_trigger"
	config_foreach get_port_trigger  "port_trigger" "$name"
	[ -z "$ptg_id" ] && return

	is_enabled=$(uci -q get port-trigger."$ptg_id".enable)

	if [ -z "$is_enabled" ] || [ "$is_enabled" = "0" ]; then
		return
	fi

	protocol=$(uci -q get port-trigger."$ptg_id".protocol)
	[ -z "$protocol" ] && return

	if [ "$protocol" = "UDP" ] || [ "$protocol" = "udp" ]; then
		IP_RULE="$IP_RULE -p udp"
		IP6_RULE="$IP6_RULE -p udp"
		IP_RULE_FWD="$IP_RULE_FWD -p udp"
	elif [ "$protocol" = "TCP" ] || [ "$protocol" = "tcp" ]; then
		IP_RULE="$IP_RULE -p tcp"
		IP6_RULE="$IP6_RULE -p tcp"
		IP_RULE_FWD="$IP_RULE_FWD -p tcp"
	else
		return
	fi

	trigger_dport=$(uci -q get port-trigger."$ptg_id".port)
	[ -z "$trigger_dport" ] && return
	IP_RULE="$IP_RULE --dport $trigger_dport"
	IP6_RULE="$IP6_RULE --dport $trigger_dport"

	trigger_dport_end=$(uci -q get port-trigger."$ptg_id".end_port_range)
	if [ -n "$trigger_dport_end" ]; then
		IP_RULE="$IP_RULE:$trigger_dport"
		IP6_RULE="$IP6_RULE:$trigger_dport"
	fi

	config_get open_protocol "$rule_id" "protocol"
	if [ "$open_protocol" = "UDP" ] || [ "$open_protocol" = "udp" ]; then
		IP_RULE="$IP_RULE -j TRIGGER --trigger-type out --trigger-proto udp"
		IP6_RULE="$IP6_RULE -j TRIGGER --trigger-type out --trigger-proto udp"
	elif [ "$open_protocol" = "TCP" ] || [ "$open_protocol" = "tcp" ]; then
		IP_RULE="$IP_RULE -j TRIGGER --trigger-type out --trigger-proto tcp"
		IP6_RULE="$IP6_RULE -j TRIGGER --trigger-type out --trigger-proto tcp"
	else
		return
	fi

	config_get open_dport "$rule_id" "port"
	[ -z "$open_dport" ] && return
	IP_RULE="$IP_RULE --trigger-match $open_dport"
	IP6_RULE="$IP6_RULE --trigger-match $open_dport"
	IP_RULE_FWD="$IP_RULE_FWD --dport $open_dport"

	config_get open_dport_end "$rule_id" "end_port_range"
	if [ -z "$open_dport_end" ]; then
		IP_RULE="$IP_RULE --trigger-relate $open_dport"
		IP6_RULE="$IP6_RULE --trigger-relate $open_dport"
	else
		IP_RULE="$IP_RULE-$open_dport_end --trigger-relate $open_dport-$open_dport_end"
		IP6_RULE="$IP6_RULE-$open_dport_end --trigger-relate $open_dport-$open_dport_end"
		IP_RULE_FWD="$IP_RULE_FWD:$open_dport_end"
	fi

	duration=$(uci -q get port-trigger."$ptg_id".auto_disable_duration)
        if [ -n "$duration" ]; then
                IP_RULE="$IP_RULE --trigger-timeout $duration"
                IP6_RULE="$IP6_RULE --trigger-timeout $duration"
        fi

	interface=$(uci -q get port-trigger."$ptg_id".src)
	[ -z "$interface" ] && return
	device=$(uci -q get network.$interface.device)
       	IP_RULE_1="iptables -w -t nat -A prerouting_porttrigger -i $device $IP_RULE"
       	echo "$IP_RULE_1">>/tmp/port_trigger_iptables

       	IP_RULE_1="ip6tables -w -t nat -A prerouting_porttrigger -i $device $IP6_RULE"
       	echo "$IP_RULE_1">>/tmp/port_trigger_ip6tables

        if [ -n "$duration" ]; then
		echo "iptables -w -t filter -A forwarding_wan_porttrigger $IP_RULE_FWD -j TRIGGER --trigger-type in --trigger-timeout $duration">>/tmp/port_trigger_iptables
		echo "ip6tables -w -t filter -A forwarding_wan_porttrigger $IP_RULE_FWD -j TRIGGER --trigger-type in --trigger-timeout $duration">>/tmp/port_trigger_ip6tables

		echo "iptables -w -t nat -A prerouting_wan_porttrigger $IP_RULE_FWD -j TRIGGER --trigger-type dnat --trigger-timeout $duration">>/tmp/port_trigger_iptables
	else
		echo "iptables -w -t filter -A forwarding_wan_porttrigger $IP_RULE_FWD -j TRIGGER --trigger-type in">>/tmp/port_trigger_iptables
		echo "ip6tables -w -t filter -A forwarding_wan_porttrigger $IP_RULE_FWD -j TRIGGER --trigger-type in">>/tmp/port_trigger_ip6tables

		echo "iptables -w -t nat -A prerouting_wan_porttrigger $IP_RULE_FWD -j TRIGGER --trigger-type dnat">>/tmp/port_trigger_iptables
	fi
}

port_trigger_add() {
	rm /tmp/port_trigger_iptables 2> /dev/null
	rm /tmp/port_trigger_ip6tables 2> /dev/null
	touch /tmp/port_trigger_iptables
	touch /tmp/port_trigger_ip6tables

	echo "iptables -w -t nat -N prerouting_porttrigger 2> /dev/null">>/tmp/port_trigger_iptables
	ret=$?
	[ $ret -eq 0 ] && echo "iptables -w -t nat -I PREROUTING -j prerouting_porttrigger 2> /dev/null">>/tmp/port_trigger_iptables
	echo "iptables -w -t filter -N forwarding_wan_porttrigger 2> /dev/null">>/tmp/port_trigger_iptables
	ret=$?
	[ $ret -eq 0 ] && echo "iptables -w -t filter -I forwarding_wan_rule -j forwarding_wan_porttrigger 2> /dev/null">>/tmp/port_trigger_iptables
	echo "iptables -w -t nat -N prerouting_wan_porttrigger 2> /dev/null">>/tmp/port_trigger_iptables
	ret=$?
	[ $ret -eq 0 ] && echo "iptables -w -t nat -A prerouting_wan_rule -j prerouting_wan_porttrigger 2> /dev/null">>/tmp/port_trigger_iptables

	echo "ip6tables -w -t nat -N prerouting_porttrigger 2> /dev/null">>/tmp/port_trigger_ip6tables
	ret=$?
	[ $ret -eq 0 ] && echo "ip6tables -w -t nat -I PREROUTING -j prerouting_porttrigger 2> /dev/null">>/tmp/port_trigger_ip6tables
	echo "ip6tables -w -t filter -N forwarding_wan_porttrigger 2> /dev/null">>/tmp/port_trigger_ip6tables
	ret=$?
	[ $ret -eq 0 ] && echo "ip6tables -w -t filter -I forwarding_wan_rule -j forwarding_wan_porttrigger 2> /dev/null">>/tmp/port_trigger_ip6tables

	# Load /etc/config/port-trigger UCI file
	config_load port-trigger
	config_foreach process_port_trigger rule

	sh /tmp/port_trigger_iptables
	sh /tmp/port_trigger_ip6tables
}

port_trigger_clean() {
	iptables -w -t nat -D PREROUTING -j prerouting_porttrigger 2> /dev/null
	iptables -w -t nat -F prerouting_porttrigger 2> /dev/null
	iptables -w -t nat -X prerouting_porttrigger 2> /dev/null
	iptables -w -t nat -D prerouting_wan_rule -j prerouting_wan_porttrigger 2> /dev/null
	iptables -w -t nat -F prerouting_wan_porttrigger 2> /dev/null
	iptables -w -t nat -X prerouting_wan_porttrigger 2> /dev/null
	iptables -w -t filter -D forwarding_wan_rule -j forwarding_wan_porttrigger 2> /dev/null
	iptables -w -t filter -F forwarding_wan_porttrigger 2> /dev/null
	iptables -w -t filter -X forwarding_wan_porttrigger 2> /dev/null
	ip6tables -w -t nat -D PREROUTING -j prerouting_porttrigger 2> /dev/null
	ip6tables -w -t nat -F prerouting_porttrigger 2> /dev/null
	ip6tables -w -t nat -X prerouting_porttrigger 2> /dev/null
	ip6tables -w -t filter -D forwarding_wan_rule -j forwarding_wan_porttrigger 2> /dev/null
	ip6tables -w -t filter -F forwarding_wan_porttrigger 2> /dev/null
	ip6tables -w -t filter -X forwarding_wan_porttrigger 2> /dev/null
}
