[backfire] firewall: backport SNAT support from trunk
[openwrt-10.03/.git] / package / firewall / files / reflection.hotplug
1 #!/bin/sh
2
3 . /etc/functions.sh
4
5 if [ "$ACTION" = "add" ] && [ "$INTERFACE" = "wan" ]; then
6         local wanip=$(uci -P/var/state get network.wan.ipaddr)
7
8         iptables -t nat -F nat_reflection_in 2>/dev/null || {
9                 iptables -t nat -N nat_reflection_in
10                 iptables -t nat -A prerouting_rule -j nat_reflection_in
11         }
12
13         iptables -t nat -F nat_reflection_out 2>/dev/null || {
14                 iptables -t nat -N nat_reflection_out
15                 iptables -t nat -A postrouting_rule -j nat_reflection_out
16         }
17
18         find_networks() {
19                 find_networks_cb() {
20                         local cfg="$1"
21                         local zone="$2"
22
23                         local name
24                         config_get name "$cfg" name
25
26                         [ "$name" = "$zone" ] && {
27                                 local network
28                                 config_get network "$cfg" network
29
30                                 echo ${network:-$zone}
31                                 return 1
32                         }
33                 }
34
35                 config_foreach find_networks_cb zone "$1"
36         }
37         
38         setup_fwd() {
39                 local cfg="$1"
40
41                 local src
42                 config_get src "$cfg" src
43
44                 local target
45                 config_get target "$cfg" target
46
47                 [ "$src" = wan ] && [ "${target:-DNAT}" = DNAT ] && {
48                         local dest
49                         config_get dest "$cfg" dest "lan"
50
51                         local net
52                         for net in $(find_networks "$dest"); do
53                                 local lanip=$(uci -P/var/state get network.$net.ipaddr)
54                                 local lanmk=$(uci -P/var/state get network.$net.netmask)
55
56                                 local proto
57                                 config_get proto "$cfg" proto
58
59                                 local reflection
60                                 config_get_bool reflection "$cfg" reflection 1
61                                 [ "$reflection" == 1 ] || return
62
63                                 local epmin epmax extport
64                                 config_get extport "$cfg" src_dport
65                                 [ -n "$extport" ] || return
66
67                                 epmin="${extport%[-:]*}"; epmax="${extport#*[-:]}"
68                                 [ "$epmin" != "$epmax" ] || epmax=""
69
70                                 local ipmin ipmax intport
71                                 config_get intport "$cfg" dest_port "$extport"
72
73                                 ipmin="${intport%[-:]*}"; ipmax="${intport#*[-:]}"
74                                 [ "$ipmin" != "$ipmax" ] || ipmax=""
75
76                                 local exthost
77                                 config_get exthost "$cfg" src_dip "$wanip"
78
79                                 local inthost
80                                 config_get inthost "$cfg" dest_ip
81                                 [ -n "$inthost" ] || return
82
83                                 [ "$proto" = tcpudp ] && proto="tcp udp"
84
85                                 local p
86                                 for p in ${proto:-tcp udp}; do
87                                         case "$p" in
88                                                 tcp|udp)
89                                                         iptables -t nat -A nat_reflection_in \
90                                                                 -s $lanip/$lanmk -d $exthost \
91                                                                 -p $p --dport $epmin${epmax:+:$epmax} \
92                                                                 -j DNAT --to $inthost:$ipmin${ipmax:+-$ipmax}
93
94                                                         iptables -t nat -A nat_reflection_out \
95                                                                 -s $lanip/$lanmk -d $inthost \
96                                                                 -p $p --dport $ipmin${ipmax:+:$ipmax} \
97                                                                 -j SNAT --to-source $lanip
98                                                 ;;
99                                         esac
100                                 done
101                         done
102                 }
103         }
104
105         config_load firewall
106         config_foreach setup_fwd redirect
107 fi
108