NAT Reflection with OpenVPN
Moderator: Moderators
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
NAT Reflection with OpenVPN
I have 1.6.2 installed on TP-Link TL-WDR4300 v1. NAT reflection works well with my forwarded ports on my LAN. However when I use Gargoyles OpenVPN Server, I am unable to access a server on my lan using my external domain name and forwarded ports. I am able to access that server directly using its lan hostname while connected via VPN, just not using its external domain name, which is how i need to access it. Is this a known limitation or does this require additional configuration?
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
Re: NAT Reflection with OpenVPN
I have tried fw3 -d reload 2>/tmp/iptables.log to get routing details with no success. It instead just prints the reload output to the log file and the iptables to the screen (shown below) Does anyone with a better understanding of iptables see the issue?
Code: Select all
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -F delegate_input
iptables -t filter -F delegate_output
iptables -t filter -F delegate_forward
iptables -t filter -F reject
iptables -t filter -F syn_flood
iptables -t filter -X syn_flood
iptables -t filter -F zone_lan_input
iptables -t filter -F zone_lan_output
iptables -t filter -F zone_lan_forward
iptables -t filter -F zone_lan_src_ACCEPT
iptables -t filter -X zone_lan_src_ACCEPT
iptables -t filter -F zone_lan_src_REJECT
iptables -t filter -X zone_lan_src_REJECT
iptables -t filter -F zone_lan_dest_ACCEPT
iptables -t filter -X zone_lan_dest_ACCEPT
iptables -t filter -F zone_wan_input
iptables -t filter -F zone_wan_output
iptables -t filter -F zone_wan_forward
iptables -t filter -F zone_wan_src_REJECT
iptables -t filter -X zone_wan_src_REJECT
iptables -t filter -F zone_wan_dest_ACCEPT
iptables -t filter -D zone_vpn_forward 2
iptables -t filter -X zone_wan_dest_ACCEPT
iptables -t filter -F zone_vpn_input
iptables -t filter -F zone_vpn_output
iptables -t filter -F zone_vpn_forward
iptables -t filter -F zone_vpn_src_ACCEPT
iptables -t filter -X zone_vpn_src_ACCEPT
iptables -t filter -F zone_vpn_dest_ACCEPT
iptables -t filter -X zone_vpn_dest_ACCEPT
iptables -t nat -F delegate_prerouting
iptables -t nat -F delegate_postrouting
iptables -t nat -F zone_lan_postrouting
iptables -t nat -X zone_lan_postrouting
iptables -t nat -F zone_lan_prerouting
iptables -t nat -X zone_lan_prerouting
iptables -t nat -F zone_wan_postrouting
iptables -t nat -X zone_wan_postrouting
iptables -t nat -F zone_wan_prerouting
iptables -t nat -X zone_wan_prerouting
iptables -t nat -F zone_vpn_postrouting
iptables -t nat -X zone_vpn_postrouting
iptables -t nat -F zone_vpn_prerouting
iptables -t nat -X zone_vpn_prerouting
iptables -t mangle -F mssfix
iptables -t mangle -F fwmark
iptables -t raw -F notrack
iptables -t filter -P INPUT ACCEPT
iptables -t filter -P OUTPUT ACCEPT
iptables -t filter -P FORWARD DROP
iptables -t filter -N delegate_input
iptables -t filter -N delegate_output
iptables -t filter -N delegate_forward
iptables -t filter -N reject
iptables -t filter -N syn_flood
iptables -t filter -N zone_lan_input
iptables -t filter -N zone_lan_output
iptables -t filter -N zone_lan_forward
iptables -t filter -N zone_lan_src_ACCEPT
iptables -t filter -N zone_lan_src_REJECT
iptables -t filter -N zone_lan_dest_ACCEPT
iptables -t filter -A zone_lan_input -m comment --comment "user chain for input" -j input_lan_rule
iptables -t filter -A zone_lan_output -m comment --comment "user chain for output" -j output_lan_rule
iptables -t filter -A zone_lan_forward -m comment --comment "user chain for forwarding" -j forwarding_lan_rule
iptables -t filter -N zone_wan_input
iptables -t filter -N zone_wan_output
iptables -t filter -N zone_wan_forward
iptables -t filter -N zone_wan_src_REJECT
iptables -t filter -N zone_wan_dest_ACCEPT
iptables -t filter -A zone_wan_input -m comment --comment "user chain for input" -j input_wan_rule
iptables -t filter -A zone_wan_output -m comment --comment "user chain for output" -j output_wan_rule
iptables -t filter -A zone_wan_forward -m comment --comment "user chain for forwarding" -j forwarding_wan_rule
iptables -t filter -N zone_vpn_input
iptables -t filter -N zone_vpn_output
iptables -t filter -N zone_vpn_forward
iptables -t filter -N zone_vpn_src_ACCEPT
iptables -t filter -N zone_vpn_dest_ACCEPT
iptables -t filter -A zone_vpn_input -m comment --comment "user chain for input" -j input_vpn_rule
iptables -t filter -A zone_vpn_output -m comment --comment "user chain for output" -j output_vpn_rule
iptables -t filter -A zone_vpn_forward -m comment --comment "user chain for forwarding" -j forwarding_vpn_rule
iptables -t filter -D INPUT -j delegate_input
iptables -t filter -A INPUT -j delegate_input
iptables -t filter -D OUTPUT -j delegate_output
iptables -t filter -A OUTPUT -j delegate_output
iptables -t filter -D FORWARD -j delegate_forward
iptables -t filter -A FORWARD -j delegate_forward
iptables -t filter -A delegate_input -i lo -j ACCEPT
iptables -t filter -A delegate_output -o lo -j ACCEPT
iptables -t filter -A delegate_input -m comment --comment "user chain for input" -j input_rule
iptables -t filter -A delegate_output -m comment --comment "user chain for output" -j output_rule
iptables -t filter -A delegate_forward -m comment --comment "user chain for forwarding" -j forwarding_rule
iptables -t filter -A delegate_input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A delegate_output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A delegate_forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A syn_flood -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 25/sec --limit-burst 50 -j RETURN
iptables -t filter -A syn_flood -j DROP
iptables -t filter -A delegate_input -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood
iptables -t filter -A reject -p tcp -j REJECT --reject-with tcp-reset
iptables -t filter -A reject -j REJECT --reject-with icmp-port-unreachable
iptables -t filter -A zone_wan_input -p udp -m udp --dport 68 -m comment --comment "Allow-DHCP-Renew" -j ACCEPT
iptables -t filter -A zone_wan_input -p icmp -m icmp --icmp-type 8 -m comment --comment "Allow-Ping" -j ACCEPT
iptables -t filter -A zone_wan_forward -p tcp -d 192.168.10.195/32 -m tcp --dport 80 -m comment --comment "http" -j ACCEPT
iptables -t filter -A zone_lan_forward -p tcp -s 192.168.10.128/25 -d 192.168.10.195/32 -m tcp --dport 80 -m comment --comment "http (reflection)" -j zone_lan_dest_ACCEPT
iptables -t filter -A zone_wan_forward -p udp -d 192.168.10.195/32 -m udp --dport 80 -m comment --comment "http" -j ACCEPT
iptables -t filter -A zone_lan_forward -p udp -s 192.168.10.128/25 -d 192.168.10.195/32 -m udp --dport 80 -m comment --comment "http (reflection)" -j zone_lan_dest_ACCEPT
iptables -t filter -A zone_lan_forward -m comment --comment "forwarding lan -> wan" -j zone_wan_dest_ACCEPT
iptables -t filter -A zone_lan_forward -m comment --comment "forwarding lan -> vpn" -j zone_vpn_dest_ACCEPT
iptables -t filter -A zone_vpn_forward -m comment --comment "forwarding vpn -> wan" -j zone_wan_dest_ACCEPT
iptables -t filter -A zone_lan_input -j zone_lan_src_ACCEPT
iptables -t filter -A zone_lan_forward -j zone_lan_src_REJECT
iptables -t filter -A zone_lan_output -j zone_lan_dest_ACCEPT
iptables -t filter -A zone_lan_src_ACCEPT -i br-lan -j ACCEPT
iptables -t filter -A zone_lan_dest_ACCEPT -o br-lan -j ACCEPT
iptables -t filter -A zone_lan_src_REJECT -i br-lan -j reject
iptables -t filter -A delegate_input -i br-lan -j zone_lan_input
iptables -t filter -A delegate_output -o br-lan -j zone_lan_output
iptables -t filter -A delegate_forward -i br-lan -j zone_lan_forward
iptables -t filter -A zone_wan_input -j zone_wan_src_REJECT
iptables -t filter -A zone_wan_forward -j zone_wan_src_REJECT
iptables -t filter -A zone_wan_output -j zone_wan_dest_ACCEPT
iptables -t filter -A zone_wan_dest_ACCEPT -o eth0.2 -j ACCEPT
iptables -t filter -A zone_wan_src_REJECT -i eth0.2 -j reject
iptables -t filter -A delegate_input -i eth0.2 -j zone_wan_input
iptables -t filter -A delegate_output -o eth0.2 -j zone_wan_output
iptables -t filter -A delegate_forward -i eth0.2 -j zone_wan_forward
iptables -t filter -A zone_vpn_forward -j zone_vpn_src_ACCEPT
iptables -t filter -A zone_vpn_output -j zone_vpn_dest_ACCEPT
iptables -t filter -A zone_vpn_src_ACCEPT -i tun+ -j ACCEPT
iptables -t filter -A zone_vpn_dest_ACCEPT -o tun+ -j ACCEPT
iptables -t filter -A delegate_input -i tun+ -j zone_vpn_input
iptables -t filter -A delegate_output -o tun+ -j zone_vpn_output
iptables -t filter -A delegate_forward -i tun+ -j zone_vpn_forward
iptables -t filter -A zone_vpn_src_ACCEPT -i tun0 -j ACCEPT
iptables -t filter -A zone_vpn_dest_ACCEPT -o tun0 -j ACCEPT
iptables -t filter -A delegate_input -i tun0 -j zone_vpn_input
iptables -t filter -A delegate_output -o tun0 -j zone_vpn_output
iptables -t filter -A delegate_forward -i tun0 -j zone_vpn_forward
iptables -t filter -A delegate_forward -j reject
iptables -t nat -N delegate_prerouting
iptables -t nat -N delegate_postrouting
iptables -t nat -N zone_lan_postrouting
iptables -t nat -N zone_lan_prerouting
iptables -t nat -A zone_lan_prerouting -m comment --comment "user chain for prerouting" -j prerouting_lan_rule
iptables -t nat -A zone_lan_postrouting -m comment --comment "user chain for postrouting" -j postrouting_lan_rule
iptables -t nat -N zone_wan_postrouting
iptables -t nat -N zone_wan_prerouting
iptables -t nat -A zone_wan_prerouting -m comment --comment "user chain for prerouting" -j prerouting_wan_rule
iptables -t nat -A zone_wan_postrouting -m comment --comment "user chain for postrouting" -j postrouting_wan_rule
iptables -t nat -N zone_vpn_postrouting
iptables -t nat -N zone_vpn_prerouting
iptables -t nat -A zone_vpn_prerouting -m comment --comment "user chain for prerouting" -j prerouting_vpn_rule
iptables -t nat -A zone_vpn_postrouting -m comment --comment "user chain for postrouting" -j postrouting_vpn_rule
iptables -t nat -D PREROUTING -j delegate_prerouting
iptables -t nat -A PREROUTING -j delegate_prerouting
iptables -t nat -D POSTROUTING -j delegate_postrouting
iptables -t nat -A POSTROUTING -j delegate_postrouting
iptables -t nat -A delegate_prerouting -m comment --comment "user chain for prerouting" -j prerouting_rule
iptables -t nat -A delegate_postrouting -m comment --comment "user chain for postrouting" -j postrouting_rule
iptables -t nat -A zone_wan_prerouting -p tcp -m tcp --dport 80 -m comment --comment "http" -j DNAT --to-destination 192.168.10.195:80
iptables -t nat -A zone_lan_prerouting -p tcp -s 192.168.10.128/25 -d [My IP]/32 -m tcp --dport 80 -m comment --comment "http (reflection)" -j DNAT --to-destination 192.168.10.195:80
iptables -t nat -A zone_lan_postrouting -p tcp -s 192.168.10.128/25 -d 192.168.10.195/32 -m tcp --dport 80 -m comment --comment "http (reflection)" -j SNAT --to-source 192.168.10.130
iptables -t nat -A zone_wan_prerouting -p udp -m udp --dport 80 -m comment --comment "http" -j DNAT --to-destination 192.168.10.195:80
iptables -t nat -A zone_lan_prerouting -p udp -s 192.168.10.128/25 -d [My IP]/32 -m udp --dport 80 -m comment --comment "http (reflection)" -j DNAT --to-destination 192.168.10.195:80
iptables -t nat -A zone_lan_postrouting -p udp -s 192.168.10.128/25 -d 192.168.10.195/32 -m udp --dport 80 -m comment --comment "http (reflection)" -j SNAT --to-source 192.168.10.130
iptables -t nat -A delegate_prerouting -i br-lan -j zone_lan_prerouting
iptables -t nat -A delegate_postrouting -o br-lan -j zone_lan_postrouting
iptables -t nat -A zone_wan_postrouting -j MASQUERADE
iptables -t nat -A delegate_prerouting -i eth0.2 -j zone_wan_prerouting
iptables -t nat -A delegate_postrouting -o eth0.2 -j zone_wan_postrouting
iptables -t nat -A zone_vpn_postrouting -j MASQUERADE
iptables -t nat -A delegate_prerouting -i tun+ -j zone_vpn_prerouting
iptables -t nat -A delegate_postrouting -o tun+ -j zone_vpn_postrouting
iptables -t nat -A delegate_prerouting -i tun0 -j zone_vpn_prerouting
iptables -t nat -A delegate_postrouting -o tun0 -j zone_vpn_postrouting
iptables -t mangle -N mssfix
iptables -t mangle -N fwmark
iptables -t mangle -D FORWARD -j mssfix
iptables -t mangle -A FORWARD -j mssfix
iptables -t mangle -D PREROUTING -j fwmark
iptables -t mangle -A PREROUTING -j fwmark
iptables -t mangle -A mssfix -p tcp -o eth0.2 -m tcp --tcp-flags SYN,RST SYN -m comment --comment "wan (mtu_fix)" -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A mssfix -p tcp -o tun+ -m tcp --tcp-flags SYN,RST SYN -m comment --comment "vpn (mtu_fix)" -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A mssfix -p tcp -o tun0 -m tcp --tcp-flags SYN,RST SYN -m comment --comment "vpn (mtu_fix)" -j TCPMSS --clamp-mss-to-pmtu
iptables -t raw -N notrack
iptables -t raw -D PREROUTING -j notrack
iptables -t raw -A PREROUTING -j notrack
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
Re: NAT Reflection with OpenVPN
After creating the forwarding rules in the gargoyle ui, I can ssh into the router and duplicate the rules (found in /etc/config/firewall), changing the src to 'vpn'. This works until I make a change in the ui which rewrites vpn back to wan.
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
Re: NAT Reflection with OpenVPN
The following diff resolves the issue. It could be cleaned up some but it allows port forwards to work for the vpn zone.
Code: Select all
diff --git a/package/gargoyle/files/www/js/port_forwarding.js b/package/gargoyle/files/www/js/port_forwarding.js
index b74c27f..d44d99e 100644
--- a/package/gargoyle/files/www/js/port_forwarding.js
+++ b/package/gargoyle/files/www/js/port_forwarding.js
@@ -49,20 +49,23 @@ function saveChanges()
var protos = rowData[1].toLowerCase() == UI.both.toLowerCase() ? ["tcp", "udp"] : [ rowData[1].toLowerCase() ];
var protoIndex=0;
+ var zones=["wan","vpn"];
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
- var id = "redirect_" + (enabled ? "enabled" : "disabled") + "_number_" + (enabled ? enabledIndex : disabledIndex);
- firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "name", rowData[0]);
- uci.set("firewall", id, "src", "wan");
- uci.set("firewall", id, "dest", "lan");
- uci.set("firewall", id, "proto", protos[protoIndex]);
- uci.set("firewall", id, "src_dport", rowData[2]);
- uci.set("firewall", id, "dest_ip", rowData[3]);
- uci.set("firewall", id, "dest_port", rowData[4]);
- enabledIndex = enabledIndex + (enabled ? 1 : 0);
- disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
+ var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
+ firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "name", rowData[0]);
+ uci.set("firewall", id, "src", zones[zoneIndex] );
+ uci.set("firewall", id, "dest", "lan");
+ uci.set("firewall", id, "proto", protos[protoIndex]);
+ uci.set("firewall", id, "src_dport", rowData[2]);
+ uci.set("firewall", id, "dest_ip", rowData[3]);
+ uci.set("firewall", id, "dest_port", rowData[4]);
+ enabledIndex = enabledIndex + (enabled ? 1 : 0);
+ disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ }
}
}
@@ -78,19 +81,21 @@ function saveChanges()
var protoIndex=0;
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
- var id = "redirect_" + (enabled ? "enabled" : "disabled") + "_number_" + (enabled ? enabledIndex : disabledIndex);
- firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "name", rowData[0]);
- uci.set("firewall", id, "src", "wan");
- uci.set("firewall", id, "dest", "lan");
- uci.set("firewall", id, "proto", protos[protoIndex]);
- uci.set("firewall", id, "src_dport", rowData[2] + "-" + rowData[3]);
- uci.set("firewall", id, "dest_port", rowData[2] + "-" + rowData[3]);
- uci.set("firewall", id, "dest_ip", rowData[4]);
-
- enabledIndex = enabledIndex + (enabled ? 1 : 0);
- disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
+ var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
+ firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "name", rowData[0]);
+ uci.set("firewall", id, "src", zones[zoneIndex]);
+ uci.set("firewall", id, "dest", "lan");
+ uci.set("firewall", id, "proto", protos[protoIndex]);
+ uci.set("firewall", id, "src_dport", rowData[2] + "-" + rowData[3]);
+ uci.set("firewall", id, "dest_port", rowData[2] + "-" + rowData[3]);
+ uci.set("firewall", id, "dest_ip", rowData[4]);
+
+ enabledIndex = enabledIndex + (enabled ? 1 : 0);
+ disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ }
}
}
@@ -424,6 +429,8 @@ function resetData()
for(rdIndex=0; rdIndex < redirectSections.length; rdIndex++)
{
var rId = redirectSections[rdIndex];
+ if( uciOriginal.get("firewall", rId, "src") == "vpn" ) continue;
+
var name = uciOriginal.get("firewall", rId, "name");
name = name == "" ? "-" : name;
var proto = uciOriginal.get("firewall", rId, "proto").toLowerCase();
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
Re: NAT Reflection with OpenVPN
This results in the file below. As a workaround for others, you may copy this file to /www/js/port_forwarding.js on your gargoyle router to give you port forwards via nat reflection when using openvpn.
Code: Select all
/*
* This program is copyright © 2008-2013 Eric Bishop and is distributed under the terms of the GNU GPL
* version 2.0 with a special clarification/exception that permits adapting the program to
* configure proprietary "back end" software provided that all modifications to the web interface
* itself remain covered by the GPL.
* See http://gargoyle-router.com/faq.html#qfoss for more information
*/
var prtS=new Object(); //part of i18n
function saveChanges()
{
errorList = proofreadAll();
if(errorList.length > 0)
{
errorString = errorList.join("\n") + "\n\n"+UI.ErrChanges;
alert(errorString);
}
else
{
setControlsEnabled(false, true);
var firewallSectionCommands = [];
var redirectSectionTypes = ["redirect", "redirect_disabled", "dmz"];
for(typeIndex=0; typeIndex < redirectSectionTypes.length; typeIndex++)
{
var sectionType = redirectSectionTypes[typeIndex];
var sections = uciOriginal.getAllSectionsOfType("firewall", sectionType);
while(sections.length > 0)
{
var lastSection = sections.pop();
uciOriginal.removeSection("firewall", lastSection);
firewallSectionCommands.push("uci del firewall." + lastSection);
}
}
var uci = uciOriginal.clone();
var singlePortTable = document.getElementById('portf_table_container').firstChild;
var singlePortData= getTableDataArray(singlePortTable, true, false);
var enabledIndex = 0;
var disabledIndex = 0;
for(rowIndex = 0; rowIndex < singlePortData.length; rowIndex++)
{
var rowData = singlePortData[rowIndex];
var enabled = rowData[5].checked;
var protos = rowData[1].toLowerCase() == UI.both.toLowerCase() ? ["tcp", "udp"] : [ rowData[1].toLowerCase() ];
var protoIndex=0;
var zones=["wan","vpn"];
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "name", rowData[0]);
uci.set("firewall", id, "src", zones[zoneIndex] );
uci.set("firewall", id, "dest", "lan");
uci.set("firewall", id, "proto", protos[protoIndex]);
uci.set("firewall", id, "src_dport", rowData[2]);
uci.set("firewall", id, "dest_ip", rowData[3]);
uci.set("firewall", id, "dest_port", rowData[4]);
enabledIndex = enabledIndex + (enabled ? 1 : 0);
disabledIndex = disabledIndex + (enabled ? 0 : 1);
}
}
}
var portRangeTable = document.getElementById('portfrange_table_container').firstChild;
var portRangeData= getTableDataArray(portRangeTable, true, false);
for(rowIndex = 0; rowIndex < portRangeData.length; rowIndex++)
{
var rowData = portRangeData[rowIndex];
var enabled = rowData[5].checked;
var protos = rowData[1].toLowerCase() == UI.both.toLowerCase() ? ["tcp", "udp"] : [ rowData[1].toLowerCase() ];
var protoIndex=0;
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "name", rowData[0]);
uci.set("firewall", id, "src", zones[zoneIndex]);
uci.set("firewall", id, "dest", "lan");
uci.set("firewall", id, "proto", protos[protoIndex]);
uci.set("firewall", id, "src_dport", rowData[2] + "-" + rowData[3]);
uci.set("firewall", id, "dest_port", rowData[2] + "-" + rowData[3]);
uci.set("firewall", id, "dest_ip", rowData[4]);
enabledIndex = enabledIndex + (enabled ? 1 : 0);
disabledIndex = disabledIndex + (enabled ? 0 : 1);
}
}
}
//dmz
if(document.getElementById('dmz_enabled').checked )
{
var id = "dmz";
firewallSectionCommands.push("uci firewall.dmz=dmz" );
uci.set("firewall", id, "", "dmz");
uci.set("firewall", id, "from", "wan");
uci.set("firewall", id, "to_ip", document.getElementById('dmz_ip').value);
}
firewallSectionCommands.push("uci commit");
restartFirewallCommand = "\nsh /usr/lib/gargoyle/restart_firewall.sh ;\n";
//upnp
upnpStartCommands = new Array();
upnpdEnabled = document.getElementById("upnp_enabled").checked;
if(upnpdEnabled)
{
upnpStartCommands.push("/etc/init.d/miniupnpd enable");
uci.set("upnpd", "config", "enable_upnp", "1");
uci.set("upnpd", "config", "enable_natpmp", "1");
uci.set("upnpd", "config", "upload", document.getElementById("upnp_up").value);
uci.set("upnpd", "config", "download", document.getElementById("upnp_down").value);
}
else
{
uci.set("upnpd", "config", "enable_upnp", "0");
uci.set("upnpd", "config", "enable_natpmp", "0");
upnpStartCommands.push("/etc/init.d/miniupnpd disable");
}
commands = firewallSectionCommands.join("\n") + "\n" + uci.getScriptCommands(uciOriginal) + "\n" + upnpStartCommands.join("\n") + "\n" + restartFirewallCommand;
var param = getParameterDefinition("commands", commands) + "&" + getParameterDefinition("hash", document.cookie.replace(/^.*hash=/,"").replace(/[\t ;]+.*$/, ""));
var stateChangeFunction = function(req)
{
if(req.readyState == 4)
{
uciOriginal = uci.clone();
resetData();
setControlsEnabled(true);
}
}
runAjax("POST", "utility/run_commands.sh", param, stateChangeFunction);
}
}
function proofreadAll()
{
controlIds=['dmz_ip', 'upnp_up', 'upnp_down'];
labelIds= ['dmz_ip_label', 'upnp_up_label', 'upnp_down_label'];
functions = [validateIP, validateNumeric, validateNumeric];
returnCodes = [0,0,0];
visibilityIds=controlIds;
errors = proofreadFields(controlIds, labelIds, functions, returnCodes, visibilityIds);
return errors;
}
function addPortfRule()
{
errors = proofreadForwardSingle();
if(errors.length > 0)
{
alert(errors.join("\n") + "\n\n"+prtS.AFRErr);
}
else
{
values = new Array();
ids = ['add_desc', 'add_prot', 'add_fp', 'add_ip', 'add_dp'];
for (idIndex in ids)
{
element = document.getElementById(ids[idIndex]);
v = element.value;
v = v== '' ? '-' : v;
values.push(v);
if(element.type == "text")
{
element.value = "";
}
}
values[4] = values[4] == '-' ? values[2] : values[4];
//check if this is identical to another rule, but for a different protocol
//if so, just merge the two by setting the protocol on the old data to 'both'
//
portfTable = document.getElementById('portf_table_container').firstChild;
currentPortfData = getTableDataArray(portfTable, true, false);
otherProto = values[1] == 'TCP' ? 'UDP' : 'TCP';
mergedWithExistingRule = false;
for (rowDataIndex in currentPortfData)
{
rowData = currentPortfData[rowDataIndex];
if( otherProto == rowData[1] && values[2] == rowData[2] && values[3] == rowData[3] && values[4] == rowData[4])
{
portfTable.rows[(rowDataIndex*1)+1].childNodes[1].firstChild.data = UI.both;
if(values[0] != '-' && rowData[0] == '-')
{
portfTable.rows[(rowDataIndex*1)+1].childNodes[0].firstChild.data = values[0];
}
table1Container = document.getElementById('portf_table_container');
if(table1Container.firstChild != null)
{
table1Container.removeChild(table1Container.firstChild);
}
table1Container.appendChild(portfTable);
mergedWithExistingRule = true;
}
}
if(!mergedWithExistingRule)
{
checkbox = createInput('checkbox');
checkbox.checked = true;
values.push(checkbox);
values.push(createEditButton(true));
addTableRow(portfTable,values, true, false);
}
}
}
function addPortfRangeRule()
{
errors = proofreadForwardRange();
if(errors.length > 0)
{
alert(errors.join("\n") + "\n\n"+prtS.AFRErr);
}
else
{
values = new Array();
ids = ['addr_desc', 'addr_prot', 'addr_sp', 'addr_ep', 'addr_ip'];
for (idIndex in ids)
{
element = document.getElementById(ids[idIndex]);
v = element.value;
v = v== '' ? '-' : v;
values.push(v);
if(element.type == 'text')
{
element.value = "";
}
}
portfRangeTable = document.getElementById('portfrange_table_container').firstChild;
currentRangeData = getTableDataArray(portfRangeTable, true, false);
otherProto = values[1] == 'TCP' ? 'UDP' : 'TCP';
mergedWithExistingRule = false;
for (rowDataIndex in currentRangeData)
{
rowData = currentRangeData[rowDataIndex];
if( otherProto == rowData[1] && values[2] == rowData[2] && values[3] == rowData[3] && values[4] == rowData[4])
{
portfRangeTable.rows[(rowDataIndex*1)+1].childNodes[1].firstChild.data = UI.both;
if(values[0] != '-' && rowData[0] == '-')
{
portfRangeTable.rows[(rowDataIndex*1)+1].childNodes[0].firstChild.data = values[0];
}
table2Container = document.getElementById('portfrange_table_container');
if(table2Container.firstChild != null)
{
table2Container.removeChild(table2Container.firstChild);
}
table2Container.appendChild(portfRangeTable);
mergedWithExistingRule = true;
}
}
if(!mergedWithExistingRule)
{
checkbox = createInput('checkbox');
checkbox.checked = true;
values.push(checkbox);
values.push(createEditButton(false));
portfrangeTable = document.getElementById('portfrange_table_container').firstChild;
addTableRow(portfrangeTable,values, true, false);
}
}
}
function proofreadForwardRange(controlDocument, tableDocument, excludeRow)
{
controlDocument = controlDocument == null ? document : controlDocument;
tableDocument = tableDocument == null ? document : tableDocument;
var addIds = ['addr_sp', 'addr_ep', 'addr_ip'];
var labelIds = ['addr_sp_label', 'addr_ep_label', 'addr_ip_label'];
var functions = [validateNumeric, validateNumeric, validateIP];
var returnCodes = [0,0,0];
var visibilityIds = addIds;
var errors = proofreadFields(addIds, labelIds, functions, returnCodes, visibilityIds, controlDocument);
if(errors.length == 0)
{
if( (1*controlDocument.getElementById('addr_sp').value) > (1*controlDocument.getElementById('addr_ep').value) )
{
errors.push(prtS.GTErr);
}
var portfTable = tableDocument.getElementById('portf_table_container').firstChild;
var currentPortfData = getTableDataArray(portfTable, true, false);
var addStartPort = controlDocument.getElementById('addr_sp').value;
var addEndPort = controlDocument.getElementById('addr_ep').value;
var addProtocol = controlDocument.getElementById('addr_prot').value;
var rowDataIndex=0;
for (rowDataIndex=0; rowDataIndex < currentPortfData.length ; rowDataIndex++)
{
var rowData = currentPortfData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && addStartPort*1 <= rowData[2]*1 && addEndPort*1 >= rowData[2]*1 )
{
errors.push(prtS.DupErr);
}
}
var portfRangeTable = tableDocument.getElementById('portfrange_table_container').firstChild;
var currentRangeData = getTableDataArray(portfRangeTable, true, false);
for (rowDataIndex=0; rowDataIndex < currentRangeData.length; rowDataIndex++)
{
if(portfRangeTable.rows[rowDataIndex+1] != excludeRow)
{
var rowData = currentRangeData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && rowData[2]*1 <= addEndPort*1 && rowData[3]*1 >= addStartPort*1)
{
errors.push(prtS.DupErr);
}
}
}
}
return errors;
}
function proofreadForwardSingle(controlDocument, tableDocument, excludeRow)
{
controlDocument = controlDocument == null ? document : controlDocument;
tableDocument = tableDocument == null ? document : tableDocument;
var addIds = ['add_fp', 'add_ip'];
var labelIds = ['add_fp_label', 'add_ip_label', 'add_dp_label'];
var functions = [validateNumeric, validateIP, validateNumeric];
var returnCodes = [0,0,0];
var visibilityIds = addIds;
if(controlDocument.getElementById('add_dp').value.length > 0)
{
addIds.push('add_dp');
}
var errors = proofreadFields(addIds, labelIds, functions, returnCodes, visibilityIds, controlDocument);
if(errors.length == 0)
{
var portfTable = tableDocument.getElementById('portf_table_container').firstChild;
var currentPortfData = getTableDataArray(portfTable, true, false);
var addPort = controlDocument.getElementById('add_fp').value;
var addProtocol = controlDocument.getElementById('add_prot').value;
var rowDataIndex=0;
for (rowDataIndex=0; rowDataIndex < currentPortfData.length; rowDataIndex++)
{
if(portfTable.rows[rowDataIndex+1] != excludeRow)
{
var rowData = currentPortfData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && addPort == rowData[2])
{
errors.push(prtS.CopErr);
}
}
}
var portfRangeTable = tableDocument.getElementById('portfrange_table_container').firstChild;
var currentRangeData = getTableDataArray(portfRangeTable, true, false);
for (rowDataIndex=0; rowDataIndex < currentRangeData; rowDataIndex++)
{
var rowData = currentRangeData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && rowData[2]*1 <= addPort*1 && rowData[3]*1 >= addPort*1)
{
errors.push(prtS.CopErr);
}
}
}
return errors;
}
function resetData()
{
var singlePortTableData = new Array();
var portRangeTableData = new Array();
var singlePortEnabledStatus = new Array();
var portRangeEnabledStatus = new Array();
var dmzIp = "";
var singlePortProtoHash = [];
var portRangeProtoHash = [];
singlePortProtoHash["tcp"] = [];
singlePortProtoHash["udp"] = [];
portRangeProtoHash["tcp"] = [];
portRangeProtoHash["udp"] = [];
// parse (both enabled & disabled) redirects
// uci firewall doesn't parse redirect_disabled sections, so we can store this info there
// without any complications. Likewise we store rule name in "name" variable that doesn't
// get parsed by the uci firewall script.
var redirectSectionTypes = ["redirect", "redirect_disabled"];
for(typeIndex=0; typeIndex < redirectSectionTypes.length; typeIndex++)
{
var sectionType = redirectSectionTypes[typeIndex];
var redirectSections = uciOriginal.getAllSectionsOfType("firewall", redirectSectionTypes[typeIndex]);
for(rdIndex=0; rdIndex < redirectSections.length; rdIndex++)
{
var rId = redirectSections[rdIndex];
if( uciOriginal.get("firewall", rId, "src") == "vpn" ) continue;
var name = uciOriginal.get("firewall", rId, "name");
name = name == "" ? "-" : name;
var proto = uciOriginal.get("firewall", rId, "proto").toLowerCase();
var srcdport = uciOriginal.get("firewall", rId, "src_dport");
var destip = uciOriginal.get("firewall", rId, "dest_ip");
var destport = uciOriginal.get("firewall", rId, "dest_port");
if(srcdport == "" && destport == "" && sectionType == "redirect")
{
dmzIp = dmzIp == "" ? destip : dmzIp;
}
else if(proto.toLowerCase() == "tcp" || proto.toLowerCase() == "udp")
{
checkbox = createInput('checkbox');
checkbox.checked = sectionType == "redirect" ? true : false;
destport = destport == "" ? srcdport : destport;
otherProto = proto == "tcp" ? "udp" : "tcp";
hashStr = name + "-" + srcdport + "-" + destip + "-" + destport;
if(srcdport.match(/-/))
{
var splitPorts = srcdport.split(/-/);
// if same rule, different protocol exists, merge into one rule
// otherwise, add rule to table data
if(portRangeProtoHash[otherProto][hashStr] != null)
{
portRangeProtoHash[otherProto][hashStr][1] = UI.both;
}
else
{
var nextTableRowData = [name, proto.toUpperCase(), splitPorts[0], splitPorts[1], destip, checkbox, createEditButton(false)];
portRangeTableData.push(nextTableRowData);
portRangeProtoHash[proto][hashStr] = nextTableRowData;
portRangeEnabledStatus.push(checkbox.checked);
}
}
else
{
// if same rule, different protocol exists, merge into one rule
// otherwise, add rule to table data
if(singlePortProtoHash[otherProto][hashStr] != null)
{
singlePortProtoHash[otherProto][hashStr][1] = UI.both;
}
else
{
var nextTableRowData = [name, proto.toUpperCase(), srcdport, destip, destport, checkbox, createEditButton(true)];
singlePortTableData.push(nextTableRowData);
singlePortProtoHash[proto][hashStr] = nextTableRowData;
singlePortEnabledStatus.push(checkbox.checked);
}
}
}
}
}
columnNames = [prtS.Desc, prtS.Proto, prtS.FPrt, prtS.TIP, prtS.TPrt, UI.Enabled, '']
portfTable=createTable(columnNames, singlePortTableData, "portf_table", true, false);
table1Container = document.getElementById('portf_table_container');
if(table1Container.firstChild != null)
{
table1Container.removeChild(table1Container.firstChild);
}
table1Container.appendChild(portfTable);
columnNames = [prtS.Desc, prtS.Proto, prtS.SPrt, prtS.EPrt, prtS.TIP, UI.Enabled, '']
portfrangeTable=createTable(columnNames, portRangeTableData, "portf_range_table", true, false);
table2Container = document.getElementById('portfrange_table_container');
if(document.getElementById('portfrange_table_container').firstChild != null)
{
table2Container.removeChild(table2Container.firstChild);
}
table2Container.appendChild(portfrangeTable);
// Because IE6 was designed by programmers whose only qualification was participation in the Special Olympics,
// checkboxes become unchecked when added to table. We need to reset checked status here.
for(spIndex = 0; spIndex < singlePortEnabledStatus.length; spIndex++)
{
singlePortTableData[spIndex][5].checked = singlePortEnabledStatus[spIndex];
}
for(prIndex = 0; prIndex < portRangeEnabledStatus.length; prIndex++)
{
portRangeTableData[prIndex][5].checked = portRangeEnabledStatus[prIndex];
}
clearIds = ['add_desc', 'add_fp', 'add_ip', 'add_dp', 'addr_desc', 'addr_sp', 'addr_ep', 'addr_ip'];
for(clearIndex = 0; clearIndex < clearIds.length; clearIndex++)
{
document.getElementById(clearIds[clearIndex]).value = '';
}
//dmz
var dmzSections = uciOriginal.getAllSectionsOfType("firewall", "dmz");
document.getElementById("dmz_enabled").checked = (dmzSections.length > 0);
if( dmzSections.length > 0)
{
document.getElementById("dmz_ip").value = uciOriginal.get("firewall", dmzSections[0], "to_ip");
}
else
{
var defaultDmz = (currentLanIp.split(/\.[^\.]*$/))[0];
var lanIpEnd = parseInt((currentLanIp.split("."))[3]);
if(lanIpEnd >= 254)
{
lanIpEnd--;
}
else
{
lanIpEnd++;
}
defaultDmz = defaultDmz + "." + lanIpEnd;
document.getElementById("dmz_ip").value = defaultDmz;
}
setDmzEnabled();
//upnp
document.getElementById("upnp_enabled").checked = upnpdEnabled;
upElement = document.getElementById("upnp_up");
downElement = document.getElementById("upnp_down");
upElement.value = uciOriginal.get("upnpd", "config", "upload");
upElement.value = upElement.value == '' ? 1250 : upElement.value;
downElement.value = uciOriginal.get("upnpd", "config", "download");
downElement.value = downElement.value == '' ? 1250 : downElement.value;
setUpnpEnabled();
initializeDescriptionVisibility(uciOriginal, "upnp_help");
uciOriginal.removeSection("gargoyle", "help"); //necessary, or we over-write the help settings when we save
if (upnpdEnabled) {
update_upnp();
timerid=setInterval("update_upnp()", 10000);
} else {
clearInterval(timerid);
timerid = null;
var tableData = new Array();
var tableRow =['***','***********','***** '];
tableData.push(tableRow);
var columnNames= [prtS.Prot, prtS.LHst, prtS.Port ];
var upnpTable = createTable(columnNames, tableData, "upnp_table", false, false);
var tableContainer = document.getElementById('upnp_table_container');
if(tableContainer.firstChild != null)
{
tableContainer.removeChild(tableContainer.firstChild);
}
tableContainer.appendChild(upnpTable);
}
}
function setUpnpEnabled()
{
enableAssociatedField(document.getElementById("upnp_enabled"), 'upnp_up', document.getElementById('upnp_up').value);
enableAssociatedField(document.getElementById("upnp_enabled"), 'upnp_down', document.getElementById('upnp_down').value);
}
function setDmzEnabled()
{
enableAssociatedField(document.getElementById("dmz_enabled"), 'dmz_ip', document.getElementById('dmz_ip').value);
}
function createEditButton(isSingle)
{
var editButton = createInput("button");
editButton.value = UI.Edit;
editButton.className="default_button";
editButton.onclick = isSingle ? function(){ editForward(true, this); } : function(){ editForward(false, this); } ;
return editButton;
}
function editForward(isSingle, triggerElement)
{
if( typeof(editForwardWindow) != "undefined" )
{
//opera keeps object around after
//window is closed, so we need to deal
//with error condition
try
{
editForwardWindow.close();
}
catch(e){}
}
try
{
xCoor = window.screenX + 225;
yCoor = window.screenY+ 225;
}
catch(e)
{
xCoor = window.left + 225;
yCoor = window.top + 225;
}
var editLocation = isSingle ? "single_forward_edit.sh" : "multi_forward_edit.sh";
editForwardWindow = window.open(editLocation, "edit", "width=560,height=180,left=" + xCoor + ",top=" + yCoor );
saveButton = createInput("button", editForwardWindow.document);
closeButton = createInput("button", editForwardWindow.document);
saveButton.value = UI.CApplyChanges;
saveButton.className = "default_button";
closeButton.value = UI.CDiscardChanges;
closeButton.className = "default_button";
editRow=triggerElement.parentNode.parentNode;
runOnEditorLoaded = function ()
{
updateDone=false;
if(editForwardWindow.document != null)
{
if(editForwardWindow.document.getElementById("bottom_button_container") != null)
{
editForwardWindow.document.getElementById("bottom_button_container").appendChild(saveButton);
editForwardWindow.document.getElementById("bottom_button_container").appendChild(closeButton);
//set edit values
var r= isSingle ? "" : "r";
editForwardWindow.document.getElementById("add" + r + "_button").style.display="none";
editForwardWindow.document.getElementById("add" + r + "_desc").value = editRow.childNodes[0].firstChild.data;
setSelectedText("add" + r + "_prot", editRow.childNodes[1].firstChild.data, editForwardWindow.document);
if(isSingle)
{
editForwardWindow.document.getElementById("add_fp").value = editRow.childNodes[2].firstChild.data;
editForwardWindow.document.getElementById("add_ip").value = editRow.childNodes[3].firstChild.data;
editForwardWindow.document.getElementById("add_dp").value = editRow.childNodes[4].firstChild.data;
}
else
{
editForwardWindow.document.getElementById("addr_sp").value = editRow.childNodes[2].firstChild.data;
editForwardWindow.document.getElementById("addr_ep").value = editRow.childNodes[3].firstChild.data;
editForwardWindow.document.getElementById("addr_ip").value = editRow.childNodes[4].firstChild.data;
}
closeButton.onclick = function()
{
editForwardWindow.close();
}
saveButton.onclick = function()
{
// error checking goes here
var errors;
if(isSingle)
{
errors = proofreadForwardSingle(editForwardWindow.document, document, editRow);
}
else
{
errors = proofreadForwardRange(editForwardWindow.document, document, editRow);
}
if(errors.length > 0)
{
alert(errors.join("\n") + "\n"+prtS.UpErr);
}
else
{
//update document with new data
editRow.childNodes[0].firstChild.data = editForwardWindow.document.getElementById("add" + r + "_desc").value;
editRow.childNodes[1].firstChild.data = getSelectedValue( "add" + r + "_prot", editForwardWindow.document );
if(isSingle)
{
editRow.childNodes[2].firstChild.data = editForwardWindow.document.getElementById("add_fp").value;
editRow.childNodes[3].firstChild.data = editForwardWindow.document.getElementById("add_ip").value;
editRow.childNodes[4].firstChild.data = editForwardWindow.document.getElementById("add_dp").value;
}
else
{
editRow.childNodes[2].firstChild.data = editForwardWindow.document.getElementById("addr_sp").value;
editRow.childNodes[3].firstChild.data = editForwardWindow.document.getElementById("addr_ep").value;
editRow.childNodes[4].firstChild.data = editForwardWindow.document.getElementById("addr_ip").value;
}
editForwardWindow.close();
}
}
editForwardWindow.moveTo(xCoor,yCoor);
editForwardWindow.focus();
updateDone = true;
}
}
if(!updateDone)
{
setTimeout( "runOnEditorLoaded()", 250);
}
}
runOnEditorLoaded();
}
var updateInProgress=false;
var timerid=null;
function update_upnp()
{
if (!updateInProgress)
{
updateInProgress = true;
var commands="iptables -nL MINIUPNPD | grep ACCEPT"
var param = getParameterDefinition("commands", commands) + "&" + getParameterDefinition("hash", document.cookie.replace(/^.*hash=/,"").replace(/[\t ;]+.*$/, ""));
var stateChangeFunction = function(req)
{
if(req.readyState == 4)
{
var lines = req.responseText.split("\n");
var tableData = new Array();
var i;
var upnpcnt=0;
if (lines != null)
{
for(i = 0; i < lines.length; i++)
{
var upnd = lines[i].split(/\s+/);
if (typeof(upnd[6]) != "undefined") {
var tableRow =[upnd[1],upnd[4],upnd[6].substr(4)];
tableData.push(tableRow);
upnpcnt = upnpcnt+1;
}
}
}
//Always display at least on blank line
if (upnpcnt == 0 ) {
var tableRow =['***','***********','***** '];
tableData.push(tableRow);
}
var columnNames= [prtS.Prot, prtS.LHst, prtS.Port ];
var upnpTable = createTable(columnNames, tableData, "upnp_table", false, false);
var tableContainer = document.getElementById('upnp_table_container');
if(tableContainer.firstChild != null)
{
tableContainer.removeChild(tableContainer.firstChild);
}
tableContainer.appendChild(upnpTable);
updateInProgress = false;
}
}
runAjax("POST", "utility/run_commands.sh", param, stateChangeFunction);
}
}
-
- Posts: 7
- Joined: Sun Oct 12, 2014 6:20 pm
Re: NAT Reflection with OpenVPN
Fixed a small routing issue, with actual external ips over the vpn. File and diff contained below
File:
Diff
File:
Code: Select all
/*
* This program is copyright © 2008-2013 Eric Bishop and is distributed under the terms of the GNU GPL
* version 2.0 with a special clarification/exception that permits adapting the program to
* configure proprietary "back end" software provided that all modifications to the web interface
* itself remain covered by the GPL.
* See http://gargoyle-router.com/faq.html#qfoss for more information
*/
var prtS=new Object(); //part of i18n
function saveChanges()
{
errorList = proofreadAll();
if(errorList.length > 0)
{
errorString = errorList.join("\n") + "\n\n"+UI.ErrChanges;
alert(errorString);
}
else
{
setControlsEnabled(false, true);
var firewallSectionCommands = [];
var redirectSectionTypes = ["redirect", "redirect_disabled", "dmz"];
for(typeIndex=0; typeIndex < redirectSectionTypes.length; typeIndex++)
{
var sectionType = redirectSectionTypes[typeIndex];
var sections = uciOriginal.getAllSectionsOfType("firewall", sectionType);
while(sections.length > 0)
{
var lastSection = sections.pop();
uciOriginal.removeSection("firewall", lastSection);
firewallSectionCommands.push("uci del firewall." + lastSection);
}
}
var uci = uciOriginal.clone();
var singlePortTable = document.getElementById('portf_table_container').firstChild;
var singlePortData= getTableDataArray(singlePortTable, true, false);
var enabledIndex = 0;
var disabledIndex = 0;
for(rowIndex = 0; rowIndex < singlePortData.length; rowIndex++)
{
var rowData = singlePortData[rowIndex];
var enabled = rowData[5].checked;
var protos = rowData[1].toLowerCase() == UI.both.toLowerCase() ? ["tcp", "udp"] : [ rowData[1].toLowerCase() ];
var protoIndex=0;
var zones=["wan","vpn"];
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "name", rowData[0]);
uci.set("firewall", id, "src", zones[zoneIndex] );
if( zones[zoneIndex] =="vpn" ){
uci.set("firewall", id, "src_dip", currentWanIp );
}
uci.set("firewall", id, "dest", "lan");
uci.set("firewall", id, "proto", protos[protoIndex]);
uci.set("firewall", id, "src_dport", rowData[2]);
uci.set("firewall", id, "dest_ip", rowData[3]);
uci.set("firewall", id, "dest_port", rowData[4]);
enabledIndex = enabledIndex + (enabled ? 1 : 0);
disabledIndex = disabledIndex + (enabled ? 0 : 1);
}
}
}
var portRangeTable = document.getElementById('portfrange_table_container').firstChild;
var portRangeData= getTableDataArray(portRangeTable, true, false);
for(rowIndex = 0; rowIndex < portRangeData.length; rowIndex++)
{
var rowData = portRangeData[rowIndex];
var enabled = rowData[5].checked;
var protos = rowData[1].toLowerCase() == UI.both.toLowerCase() ? ["tcp", "udp"] : [ rowData[1].toLowerCase() ];
var protoIndex=0;
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
uci.set("firewall", id, "name", rowData[0]);
uci.set("firewall", id, "src", zones[zoneIndex]);
if( zones[zoneIndex] =="vpn" ){
uci.set("firewall", id, "src_dip", currentWanIp );
}
uci.set("firewall", id, "dest", "lan");
uci.set("firewall", id, "proto", protos[protoIndex]);
uci.set("firewall", id, "src_dport", rowData[2] + "-" + rowData[3]);
uci.set("firewall", id, "dest_port", rowData[2] + "-" + rowData[3]);
uci.set("firewall", id, "dest_ip", rowData[4]);
enabledIndex = enabledIndex + (enabled ? 1 : 0);
disabledIndex = disabledIndex + (enabled ? 0 : 1);
}
}
}
//dmz
if(document.getElementById('dmz_enabled').checked )
{
var id = "dmz";
firewallSectionCommands.push("uci firewall.dmz=dmz" );
uci.set("firewall", id, "", "dmz");
uci.set("firewall", id, "from", "wan");
uci.set("firewall", id, "to_ip", document.getElementById('dmz_ip').value);
}
firewallSectionCommands.push("uci commit");
restartFirewallCommand = "\nsh /usr/lib/gargoyle/restart_firewall.sh ;\n";
//upnp
upnpStartCommands = new Array();
upnpdEnabled = document.getElementById("upnp_enabled").checked;
if(upnpdEnabled)
{
upnpStartCommands.push("/etc/init.d/miniupnpd enable");
uci.set("upnpd", "config", "enable_upnp", "1");
uci.set("upnpd", "config", "enable_natpmp", "1");
uci.set("upnpd", "config", "upload", document.getElementById("upnp_up").value);
uci.set("upnpd", "config", "download", document.getElementById("upnp_down").value);
}
else
{
uci.set("upnpd", "config", "enable_upnp", "0");
uci.set("upnpd", "config", "enable_natpmp", "0");
upnpStartCommands.push("/etc/init.d/miniupnpd disable");
}
commands = firewallSectionCommands.join("\n") + "\n" + uci.getScriptCommands(uciOriginal) + "\n" + upnpStartCommands.join("\n") + "\n" + restartFirewallCommand;
var param = getParameterDefinition("commands", commands) + "&" + getParameterDefinition("hash", document.cookie.replace(/^.*hash=/,"").replace(/[\t ;]+.*$/, ""));
var stateChangeFunction = function(req)
{
if(req.readyState == 4)
{
uciOriginal = uci.clone();
resetData();
setControlsEnabled(true);
}
}
runAjax("POST", "utility/run_commands.sh", param, stateChangeFunction);
}
}
function proofreadAll()
{
controlIds=['dmz_ip', 'upnp_up', 'upnp_down'];
labelIds= ['dmz_ip_label', 'upnp_up_label', 'upnp_down_label'];
functions = [validateIP, validateNumeric, validateNumeric];
returnCodes = [0,0,0];
visibilityIds=controlIds;
errors = proofreadFields(controlIds, labelIds, functions, returnCodes, visibilityIds);
return errors;
}
function addPortfRule()
{
errors = proofreadForwardSingle();
if(errors.length > 0)
{
alert(errors.join("\n") + "\n\n"+prtS.AFRErr);
}
else
{
values = new Array();
ids = ['add_desc', 'add_prot', 'add_fp', 'add_ip', 'add_dp'];
for (idIndex in ids)
{
element = document.getElementById(ids[idIndex]);
v = element.value;
v = v== '' ? '-' : v;
values.push(v);
if(element.type == "text")
{
element.value = "";
}
}
values[4] = values[4] == '-' ? values[2] : values[4];
//check if this is identical to another rule, but for a different protocol
//if so, just merge the two by setting the protocol on the old data to 'both'
//
portfTable = document.getElementById('portf_table_container').firstChild;
currentPortfData = getTableDataArray(portfTable, true, false);
otherProto = values[1] == 'TCP' ? 'UDP' : 'TCP';
mergedWithExistingRule = false;
for (rowDataIndex in currentPortfData)
{
rowData = currentPortfData[rowDataIndex];
if( otherProto == rowData[1] && values[2] == rowData[2] && values[3] == rowData[3] && values[4] == rowData[4])
{
portfTable.rows[(rowDataIndex*1)+1].childNodes[1].firstChild.data = UI.both;
if(values[0] != '-' && rowData[0] == '-')
{
portfTable.rows[(rowDataIndex*1)+1].childNodes[0].firstChild.data = values[0];
}
table1Container = document.getElementById('portf_table_container');
if(table1Container.firstChild != null)
{
table1Container.removeChild(table1Container.firstChild);
}
table1Container.appendChild(portfTable);
mergedWithExistingRule = true;
}
}
if(!mergedWithExistingRule)
{
checkbox = createInput('checkbox');
checkbox.checked = true;
values.push(checkbox);
values.push(createEditButton(true));
addTableRow(portfTable,values, true, false);
}
}
}
function addPortfRangeRule()
{
errors = proofreadForwardRange();
if(errors.length > 0)
{
alert(errors.join("\n") + "\n\n"+prtS.AFRErr);
}
else
{
values = new Array();
ids = ['addr_desc', 'addr_prot', 'addr_sp', 'addr_ep', 'addr_ip'];
for (idIndex in ids)
{
element = document.getElementById(ids[idIndex]);
v = element.value;
v = v== '' ? '-' : v;
values.push(v);
if(element.type == 'text')
{
element.value = "";
}
}
portfRangeTable = document.getElementById('portfrange_table_container').firstChild;
currentRangeData = getTableDataArray(portfRangeTable, true, false);
otherProto = values[1] == 'TCP' ? 'UDP' : 'TCP';
mergedWithExistingRule = false;
for (rowDataIndex in currentRangeData)
{
rowData = currentRangeData[rowDataIndex];
if( otherProto == rowData[1] && values[2] == rowData[2] && values[3] == rowData[3] && values[4] == rowData[4])
{
portfRangeTable.rows[(rowDataIndex*1)+1].childNodes[1].firstChild.data = UI.both;
if(values[0] != '-' && rowData[0] == '-')
{
portfRangeTable.rows[(rowDataIndex*1)+1].childNodes[0].firstChild.data = values[0];
}
table2Container = document.getElementById('portfrange_table_container');
if(table2Container.firstChild != null)
{
table2Container.removeChild(table2Container.firstChild);
}
table2Container.appendChild(portfRangeTable);
mergedWithExistingRule = true;
}
}
if(!mergedWithExistingRule)
{
checkbox = createInput('checkbox');
checkbox.checked = true;
values.push(checkbox);
values.push(createEditButton(false));
portfrangeTable = document.getElementById('portfrange_table_container').firstChild;
addTableRow(portfrangeTable,values, true, false);
}
}
}
function proofreadForwardRange(controlDocument, tableDocument, excludeRow)
{
controlDocument = controlDocument == null ? document : controlDocument;
tableDocument = tableDocument == null ? document : tableDocument;
var addIds = ['addr_sp', 'addr_ep', 'addr_ip'];
var labelIds = ['addr_sp_label', 'addr_ep_label', 'addr_ip_label'];
var functions = [validateNumeric, validateNumeric, validateIP];
var returnCodes = [0,0,0];
var visibilityIds = addIds;
var errors = proofreadFields(addIds, labelIds, functions, returnCodes, visibilityIds, controlDocument);
if(errors.length == 0)
{
if( (1*controlDocument.getElementById('addr_sp').value) > (1*controlDocument.getElementById('addr_ep').value) )
{
errors.push(prtS.GTErr);
}
var portfTable = tableDocument.getElementById('portf_table_container').firstChild;
var currentPortfData = getTableDataArray(portfTable, true, false);
var addStartPort = controlDocument.getElementById('addr_sp').value;
var addEndPort = controlDocument.getElementById('addr_ep').value;
var addProtocol = controlDocument.getElementById('addr_prot').value;
var rowDataIndex=0;
for (rowDataIndex=0; rowDataIndex < currentPortfData.length ; rowDataIndex++)
{
var rowData = currentPortfData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && addStartPort*1 <= rowData[2]*1 && addEndPort*1 >= rowData[2]*1 )
{
errors.push(prtS.DupErr);
}
}
var portfRangeTable = tableDocument.getElementById('portfrange_table_container').firstChild;
var currentRangeData = getTableDataArray(portfRangeTable, true, false);
for (rowDataIndex=0; rowDataIndex < currentRangeData.length; rowDataIndex++)
{
if(portfRangeTable.rows[rowDataIndex+1] != excludeRow)
{
var rowData = currentRangeData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && rowData[2]*1 <= addEndPort*1 && rowData[3]*1 >= addStartPort*1)
{
errors.push(prtS.DupErr);
}
}
}
}
return errors;
}
function proofreadForwardSingle(controlDocument, tableDocument, excludeRow)
{
controlDocument = controlDocument == null ? document : controlDocument;
tableDocument = tableDocument == null ? document : tableDocument;
var addIds = ['add_fp', 'add_ip'];
var labelIds = ['add_fp_label', 'add_ip_label', 'add_dp_label'];
var functions = [validateNumeric, validateIP, validateNumeric];
var returnCodes = [0,0,0];
var visibilityIds = addIds;
if(controlDocument.getElementById('add_dp').value.length > 0)
{
addIds.push('add_dp');
}
var errors = proofreadFields(addIds, labelIds, functions, returnCodes, visibilityIds, controlDocument);
if(errors.length == 0)
{
var portfTable = tableDocument.getElementById('portf_table_container').firstChild;
var currentPortfData = getTableDataArray(portfTable, true, false);
var addPort = controlDocument.getElementById('add_fp').value;
var addProtocol = controlDocument.getElementById('add_prot').value;
var rowDataIndex=0;
for (rowDataIndex=0; rowDataIndex < currentPortfData.length; rowDataIndex++)
{
if(portfTable.rows[rowDataIndex+1] != excludeRow)
{
var rowData = currentPortfData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && addPort == rowData[2])
{
errors.push(prtS.CopErr);
}
}
}
var portfRangeTable = tableDocument.getElementById('portfrange_table_container').firstChild;
var currentRangeData = getTableDataArray(portfRangeTable, true, false);
for (rowDataIndex=0; rowDataIndex < currentRangeData; rowDataIndex++)
{
var rowData = currentRangeData[rowDataIndex];
if( (addProtocol == rowData[1] || addProtocol == UI.both || rowData[1] == UI.both) && rowData[2]*1 <= addPort*1 && rowData[3]*1 >= addPort*1)
{
errors.push(prtS.CopErr);
}
}
}
return errors;
}
function resetData()
{
var singlePortTableData = new Array();
var portRangeTableData = new Array();
var singlePortEnabledStatus = new Array();
var portRangeEnabledStatus = new Array();
var dmzIp = "";
var singlePortProtoHash = [];
var portRangeProtoHash = [];
singlePortProtoHash["tcp"] = [];
singlePortProtoHash["udp"] = [];
portRangeProtoHash["tcp"] = [];
portRangeProtoHash["udp"] = [];
// parse (both enabled & disabled) redirects
// uci firewall doesn't parse redirect_disabled sections, so we can store this info there
// without any complications. Likewise we store rule name in "name" variable that doesn't
// get parsed by the uci firewall script.
var redirectSectionTypes = ["redirect", "redirect_disabled"];
for(typeIndex=0; typeIndex < redirectSectionTypes.length; typeIndex++)
{
var sectionType = redirectSectionTypes[typeIndex];
var redirectSections = uciOriginal.getAllSectionsOfType("firewall", redirectSectionTypes[typeIndex]);
for(rdIndex=0; rdIndex < redirectSections.length; rdIndex++)
{
var rId = redirectSections[rdIndex];
if( uciOriginal.get("firewall", rId, "src") == "vpn" ) continue;
var name = uciOriginal.get("firewall", rId, "name");
name = name == "" ? "-" : name;
var proto = uciOriginal.get("firewall", rId, "proto").toLowerCase();
var srcdport = uciOriginal.get("firewall", rId, "src_dport");
var destip = uciOriginal.get("firewall", rId, "dest_ip");
var destport = uciOriginal.get("firewall", rId, "dest_port");
if(srcdport == "" && destport == "" && sectionType == "redirect")
{
dmzIp = dmzIp == "" ? destip : dmzIp;
}
else if(proto.toLowerCase() == "tcp" || proto.toLowerCase() == "udp")
{
checkbox = createInput('checkbox');
checkbox.checked = sectionType == "redirect" ? true : false;
destport = destport == "" ? srcdport : destport;
otherProto = proto == "tcp" ? "udp" : "tcp";
hashStr = name + "-" + srcdport + "-" + destip + "-" + destport;
if(srcdport.match(/-/))
{
var splitPorts = srcdport.split(/-/);
// if same rule, different protocol exists, merge into one rule
// otherwise, add rule to table data
if(portRangeProtoHash[otherProto][hashStr] != null)
{
portRangeProtoHash[otherProto][hashStr][1] = UI.both;
}
else
{
var nextTableRowData = [name, proto.toUpperCase(), splitPorts[0], splitPorts[1], destip, checkbox, createEditButton(false)];
portRangeTableData.push(nextTableRowData);
portRangeProtoHash[proto][hashStr] = nextTableRowData;
portRangeEnabledStatus.push(checkbox.checked);
}
}
else
{
// if same rule, different protocol exists, merge into one rule
// otherwise, add rule to table data
if(singlePortProtoHash[otherProto][hashStr] != null)
{
singlePortProtoHash[otherProto][hashStr][1] = UI.both;
}
else
{
var nextTableRowData = [name, proto.toUpperCase(), srcdport, destip, destport, checkbox, createEditButton(true)];
singlePortTableData.push(nextTableRowData);
singlePortProtoHash[proto][hashStr] = nextTableRowData;
singlePortEnabledStatus.push(checkbox.checked);
}
}
}
}
}
columnNames = [prtS.Desc, prtS.Proto, prtS.FPrt, prtS.TIP, prtS.TPrt, UI.Enabled, '']
portfTable=createTable(columnNames, singlePortTableData, "portf_table", true, false);
table1Container = document.getElementById('portf_table_container');
if(table1Container.firstChild != null)
{
table1Container.removeChild(table1Container.firstChild);
}
table1Container.appendChild(portfTable);
columnNames = [prtS.Desc, prtS.Proto, prtS.SPrt, prtS.EPrt, prtS.TIP, UI.Enabled, '']
portfrangeTable=createTable(columnNames, portRangeTableData, "portf_range_table", true, false);
table2Container = document.getElementById('portfrange_table_container');
if(document.getElementById('portfrange_table_container').firstChild != null)
{
table2Container.removeChild(table2Container.firstChild);
}
table2Container.appendChild(portfrangeTable);
// Because IE6 was designed by programmers whose only qualification was participation in the Special Olympics,
// checkboxes become unchecked when added to table. We need to reset checked status here.
for(spIndex = 0; spIndex < singlePortEnabledStatus.length; spIndex++)
{
singlePortTableData[spIndex][5].checked = singlePortEnabledStatus[spIndex];
}
for(prIndex = 0; prIndex < portRangeEnabledStatus.length; prIndex++)
{
portRangeTableData[prIndex][5].checked = portRangeEnabledStatus[prIndex];
}
clearIds = ['add_desc', 'add_fp', 'add_ip', 'add_dp', 'addr_desc', 'addr_sp', 'addr_ep', 'addr_ip'];
for(clearIndex = 0; clearIndex < clearIds.length; clearIndex++)
{
document.getElementById(clearIds[clearIndex]).value = '';
}
//dmz
var dmzSections = uciOriginal.getAllSectionsOfType("firewall", "dmz");
document.getElementById("dmz_enabled").checked = (dmzSections.length > 0);
if( dmzSections.length > 0)
{
document.getElementById("dmz_ip").value = uciOriginal.get("firewall", dmzSections[0], "to_ip");
}
else
{
var defaultDmz = (currentLanIp.split(/\.[^\.]*$/))[0];
var lanIpEnd = parseInt((currentLanIp.split("."))[3]);
if(lanIpEnd >= 254)
{
lanIpEnd--;
}
else
{
lanIpEnd++;
}
defaultDmz = defaultDmz + "." + lanIpEnd;
document.getElementById("dmz_ip").value = defaultDmz;
}
setDmzEnabled();
//upnp
document.getElementById("upnp_enabled").checked = upnpdEnabled;
upElement = document.getElementById("upnp_up");
downElement = document.getElementById("upnp_down");
upElement.value = uciOriginal.get("upnpd", "config", "upload");
upElement.value = upElement.value == '' ? 1250 : upElement.value;
downElement.value = uciOriginal.get("upnpd", "config", "download");
downElement.value = downElement.value == '' ? 1250 : downElement.value;
setUpnpEnabled();
initializeDescriptionVisibility(uciOriginal, "upnp_help");
uciOriginal.removeSection("gargoyle", "help"); //necessary, or we over-write the help settings when we save
if (upnpdEnabled) {
update_upnp();
timerid=setInterval("update_upnp()", 10000);
} else {
clearInterval(timerid);
timerid = null;
var tableData = new Array();
var tableRow =['***','***********','***** '];
tableData.push(tableRow);
var columnNames= [prtS.Prot, prtS.LHst, prtS.Port ];
var upnpTable = createTable(columnNames, tableData, "upnp_table", false, false);
var tableContainer = document.getElementById('upnp_table_container');
if(tableContainer.firstChild != null)
{
tableContainer.removeChild(tableContainer.firstChild);
}
tableContainer.appendChild(upnpTable);
}
}
function setUpnpEnabled()
{
enableAssociatedField(document.getElementById("upnp_enabled"), 'upnp_up', document.getElementById('upnp_up').value);
enableAssociatedField(document.getElementById("upnp_enabled"), 'upnp_down', document.getElementById('upnp_down').value);
}
function setDmzEnabled()
{
enableAssociatedField(document.getElementById("dmz_enabled"), 'dmz_ip', document.getElementById('dmz_ip').value);
}
function createEditButton(isSingle)
{
var editButton = createInput("button");
editButton.value = UI.Edit;
editButton.className="default_button";
editButton.onclick = isSingle ? function(){ editForward(true, this); } : function(){ editForward(false, this); } ;
return editButton;
}
function editForward(isSingle, triggerElement)
{
if( typeof(editForwardWindow) != "undefined" )
{
//opera keeps object around after
//window is closed, so we need to deal
//with error condition
try
{
editForwardWindow.close();
}
catch(e){}
}
try
{
xCoor = window.screenX + 225;
yCoor = window.screenY+ 225;
}
catch(e)
{
xCoor = window.left + 225;
yCoor = window.top + 225;
}
var editLocation = isSingle ? "single_forward_edit.sh" : "multi_forward_edit.sh";
editForwardWindow = window.open(editLocation, "edit", "width=560,height=180,left=" + xCoor + ",top=" + yCoor );
saveButton = createInput("button", editForwardWindow.document);
closeButton = createInput("button", editForwardWindow.document);
saveButton.value = UI.CApplyChanges;
saveButton.className = "default_button";
closeButton.value = UI.CDiscardChanges;
closeButton.className = "default_button";
editRow=triggerElement.parentNode.parentNode;
runOnEditorLoaded = function ()
{
updateDone=false;
if(editForwardWindow.document != null)
{
if(editForwardWindow.document.getElementById("bottom_button_container") != null)
{
editForwardWindow.document.getElementById("bottom_button_container").appendChild(saveButton);
editForwardWindow.document.getElementById("bottom_button_container").appendChild(closeButton);
//set edit values
var r= isSingle ? "" : "r";
editForwardWindow.document.getElementById("add" + r + "_button").style.display="none";
editForwardWindow.document.getElementById("add" + r + "_desc").value = editRow.childNodes[0].firstChild.data;
setSelectedText("add" + r + "_prot", editRow.childNodes[1].firstChild.data, editForwardWindow.document);
if(isSingle)
{
editForwardWindow.document.getElementById("add_fp").value = editRow.childNodes[2].firstChild.data;
editForwardWindow.document.getElementById("add_ip").value = editRow.childNodes[3].firstChild.data;
editForwardWindow.document.getElementById("add_dp").value = editRow.childNodes[4].firstChild.data;
}
else
{
editForwardWindow.document.getElementById("addr_sp").value = editRow.childNodes[2].firstChild.data;
editForwardWindow.document.getElementById("addr_ep").value = editRow.childNodes[3].firstChild.data;
editForwardWindow.document.getElementById("addr_ip").value = editRow.childNodes[4].firstChild.data;
}
closeButton.onclick = function()
{
editForwardWindow.close();
}
saveButton.onclick = function()
{
// error checking goes here
var errors;
if(isSingle)
{
errors = proofreadForwardSingle(editForwardWindow.document, document, editRow);
}
else
{
errors = proofreadForwardRange(editForwardWindow.document, document, editRow);
}
if(errors.length > 0)
{
alert(errors.join("\n") + "\n"+prtS.UpErr);
}
else
{
//update document with new data
editRow.childNodes[0].firstChild.data = editForwardWindow.document.getElementById("add" + r + "_desc").value;
editRow.childNodes[1].firstChild.data = getSelectedValue( "add" + r + "_prot", editForwardWindow.document );
if(isSingle)
{
editRow.childNodes[2].firstChild.data = editForwardWindow.document.getElementById("add_fp").value;
editRow.childNodes[3].firstChild.data = editForwardWindow.document.getElementById("add_ip").value;
editRow.childNodes[4].firstChild.data = editForwardWindow.document.getElementById("add_dp").value;
}
else
{
editRow.childNodes[2].firstChild.data = editForwardWindow.document.getElementById("addr_sp").value;
editRow.childNodes[3].firstChild.data = editForwardWindow.document.getElementById("addr_ep").value;
editRow.childNodes[4].firstChild.data = editForwardWindow.document.getElementById("addr_ip").value;
}
editForwardWindow.close();
}
}
editForwardWindow.moveTo(xCoor,yCoor);
editForwardWindow.focus();
updateDone = true;
}
}
if(!updateDone)
{
setTimeout( "runOnEditorLoaded()", 250);
}
}
runOnEditorLoaded();
}
var updateInProgress=false;
var timerid=null;
function update_upnp()
{
if (!updateInProgress)
{
updateInProgress = true;
var commands="iptables -nL MINIUPNPD | grep ACCEPT"
var param = getParameterDefinition("commands", commands) + "&" + getParameterDefinition("hash", document.cookie.replace(/^.*hash=/,"").replace(/[\t ;]+.*$/, ""));
var stateChangeFunction = function(req)
{
if(req.readyState == 4)
{
var lines = req.responseText.split("\n");
var tableData = new Array();
var i;
var upnpcnt=0;
if (lines != null)
{
for(i = 0; i < lines.length; i++)
{
var upnd = lines[i].split(/\s+/);
if (typeof(upnd[6]) != "undefined") {
var tableRow =[upnd[1],upnd[4],upnd[6].substr(4)];
tableData.push(tableRow);
upnpcnt = upnpcnt+1;
}
}
}
//Always display at least on blank line
if (upnpcnt == 0 ) {
var tableRow =['***','***********','***** '];
tableData.push(tableRow);
}
var columnNames= [prtS.Prot, prtS.LHst, prtS.Port ];
var upnpTable = createTable(columnNames, tableData, "upnp_table", false, false);
var tableContainer = document.getElementById('upnp_table_container');
if(tableContainer.firstChild != null)
{
tableContainer.removeChild(tableContainer.firstChild);
}
tableContainer.appendChild(upnpTable);
updateInProgress = false;
}
}
runAjax("POST", "utility/run_commands.sh", param, stateChangeFunction);
}
}
Diff
Code: Select all
diff --git a/package/gargoyle/files/www/js/port_forwarding.js b/package/gargoyle/files/www/js/port_forwarding.js
index b74c27f..a633421 100644
--- a/package/gargoyle/files/www/js/port_forwarding.js
+++ b/package/gargoyle/files/www/js/port_forwarding.js
@@ -49,20 +49,26 @@ function saveChanges()
var protos = rowData[1].toLowerCase() == UI.both.toLowerCase() ? ["tcp", "udp"] : [ rowData[1].toLowerCase() ];
var protoIndex=0;
+ var zones=["wan","vpn"];
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
- var id = "redirect_" + (enabled ? "enabled" : "disabled") + "_number_" + (enabled ? enabledIndex : disabledIndex);
- firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "name", rowData[0]);
- uci.set("firewall", id, "src", "wan");
- uci.set("firewall", id, "dest", "lan");
- uci.set("firewall", id, "proto", protos[protoIndex]);
- uci.set("firewall", id, "src_dport", rowData[2]);
- uci.set("firewall", id, "dest_ip", rowData[3]);
- uci.set("firewall", id, "dest_port", rowData[4]);
- enabledIndex = enabledIndex + (enabled ? 1 : 0);
- disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
+ var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
+ firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "name", rowData[0]);
+ uci.set("firewall", id, "src", zones[zoneIndex] );
+ if( zones[zoneIndex] =="vpn" ){
+ uci.set("firewall", id, "src_dip", currentWanIp );
+ }
+ uci.set("firewall", id, "dest", "lan");
+ uci.set("firewall", id, "proto", protos[protoIndex]);
+ uci.set("firewall", id, "src_dport", rowData[2]);
+ uci.set("firewall", id, "dest_ip", rowData[3]);
+ uci.set("firewall", id, "dest_port", rowData[4]);
+ enabledIndex = enabledIndex + (enabled ? 1 : 0);
+ disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ }
}
}
@@ -78,19 +84,24 @@ function saveChanges()
var protoIndex=0;
for(protoIndex=0;protoIndex < protos.length; protoIndex++)
{
- var id = "redirect_" + (enabled ? "enabled" : "disabled") + "_number_" + (enabled ? enabledIndex : disabledIndex);
- firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
- uci.set("firewall", id, "name", rowData[0]);
- uci.set("firewall", id, "src", "wan");
- uci.set("firewall", id, "dest", "lan");
- uci.set("firewall", id, "proto", protos[protoIndex]);
- uci.set("firewall", id, "src_dport", rowData[2] + "-" + rowData[3]);
- uci.set("firewall", id, "dest_port", rowData[2] + "-" + rowData[3]);
- uci.set("firewall", id, "dest_ip", rowData[4]);
-
- enabledIndex = enabledIndex + (enabled ? 1 : 0);
- disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ for( var zoneIndex=0; zoneIndex < zones.length; zoneIndex++){
+ var id = "redirect_" + (enabled ? "enabled" : "disabled") + zones[zoneIndex] + "_number_" + (enabled ? enabledIndex : disabledIndex);
+ firewallSectionCommands.push("uci set firewall." + id + "=" + (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "", (enabled ? "redirect" : "redirect_disabled"));
+ uci.set("firewall", id, "name", rowData[0]);
+ uci.set("firewall", id, "src", zones[zoneIndex]);
+ if( zones[zoneIndex] =="vpn" ){
+ uci.set("firewall", id, "src_dip", currentWanIp );
+ }
+ uci.set("firewall", id, "dest", "lan");
+ uci.set("firewall", id, "proto", protos[protoIndex]);
+ uci.set("firewall", id, "src_dport", rowData[2] + "-" + rowData[3]);
+ uci.set("firewall", id, "dest_port", rowData[2] + "-" + rowData[3]);
+ uci.set("firewall", id, "dest_ip", rowData[4]);
+
+ enabledIndex = enabledIndex + (enabled ? 1 : 0);
+ disabledIndex = disabledIndex + (enabled ? 0 : 1);
+ }
}
}
@@ -424,6 +435,8 @@ function resetData()
for(rdIndex=0; rdIndex < redirectSections.length; rdIndex++)
{
var rId = redirectSections[rdIndex];
+ if( uciOriginal.get("firewall", rId, "src") == "vpn" ) continue;
+
var name = uciOriginal.get("firewall", rId, "name");
name = name == "" ? "-" : name;
var proto = uciOriginal.get("firewall", rId, "proto").toLowerCase();