#!/bin/sh . /etc/functions.sh if [ "$ACTION" = "add" ] && [ "$INTERFACE" = "wan" ]; then local wanip=$(uci -P/var/state get network.wan.ipaddr) iptables -t nat -F nat_reflection_in 2>/dev/null || { iptables -t nat -N nat_reflection_in iptables -t nat -A prerouting_rule -j nat_reflection_in } iptables -t nat -F nat_reflection_out 2>/dev/null || { iptables -t nat -N nat_reflection_out iptables -t nat -A postrouting_rule -j nat_reflection_out } iptables -t filter -F nat_reflection_fwd 2>/dev/null || { iptables -t filter -N nat_reflection_fwd iptables -t filter -A forwarding_rule -j nat_reflection_fwd } find_networks() { find_networks_cb() { local cfg="$1" local zone="$2" local name config_get name "$cfg" name [ "$name" = "$zone" ] && { local network config_get network "$cfg" network echo ${network:-$zone} return 1 } } config_foreach find_networks_cb zone "$1" } setup_fwd() { local cfg="$1" local reflection config_get_bool reflection "$cfg" reflection 1 [ "$reflection" == 1 ] || return local src config_get src "$cfg" src local target config_get target "$cfg" target DNAT [ "$src" = wan ] && [ "$target" = DNAT ] && { local dest config_get dest "$cfg" dest "lan" [ "$dest" != "*" ] || return local net for net in $(find_networks "$dest"); do local lanip=$(uci -P/var/state get network.$net.ipaddr) local lanmk=$(uci -P/var/state get network.$net.netmask) local proto config_get proto "$cfg" proto local epmin epmax extport config_get extport "$cfg" src_dport [ -n "$extport" ] || return epmin="${extport%[-:]*}"; epmax="${extport#*[-:]}" [ "${epmin#!}" != "$epmax" ] || epmax="" local ipmin ipmax intport config_get intport "$cfg" dest_port "$extport" ipmin="${intport%[-:]*}"; ipmax="${intport#*[-:]}" [ "${ipmin#!}" != "$ipmax" ] || ipmax="" local exthost config_get exthost "$cfg" src_dip "$wanip" local inthost config_get inthost "$cfg" dest_ip [ -n "$inthost" ] || return [ "$proto" = tcpudp ] && proto="tcp udp" [ "${inthost#!}" = "$inthost" ] || return 0 [ "${exthost#!}" = "$exthost" ] || return 0 [ "${epmin#!}" != "$epmin" ] && \ extport="! --dport ${epmin#!}${epmax:+:$epmax}" || \ extport="--dport $epmin${epmax:+:$epmax}" [ "${ipmin#!}" != "$ipmin" ] && \ intport="! --dport ${ipmin#!}${ipmax:+:$ipmax}" || \ intport="--dport $ipmin${ipmax:+:$ipmax}" local p for p in ${proto:-tcp udp}; do case "$p" in tcp|udp|6|17) iptables -t nat -A nat_reflection_in \ -s $lanip/$lanmk -d $exthost \ -p $p $extport \ -j DNAT --to $inthost:${ipmin#!}${ipmax:+-$ipmax} iptables -t nat -A nat_reflection_out \ -s $lanip/$lanmk -d $inthost \ -p $p $intport \ -j SNAT --to-source $lanip iptables -t filter -A nat_reflection_fwd \ -s $lanip/$lanmk -d $inthost \ -p $p $intport \ -j ACCEPT ;; esac done done } } config_load firewall config_foreach setup_fwd redirect fi