Merge pull request #2882 from TDT-AG/pr/20190718-ovpn-tls-ciphersuites
[project/luci.git] / applications / luci-app-firewall / htdocs / luci-static / resources / view / firewall / forwards.js
1 'use strict';
2 'require ui';
3 'require rpc';
4 'require uci';
5 'require form';
6 'require tools.firewall as fwtool';
7 'require tools.widgets as widgets';
8
9 function fmt(fmt /*, ...*/) {
10 var repl = [], wrap = false;
11
12 for (var i = 1; i < arguments.length; i++) {
13 if (L.dom.elem(arguments[i])) {
14 switch (arguments[i].nodeType) {
15 case 1:
16 repl.push(arguments[i].outerHTML);
17 wrap = true;
18 break;
19
20 case 3:
21 repl.push(arguments[i].data);
22 break;
23
24 case 11:
25 var span = E('span');
26 span.appendChild(arguments[i]);
27 repl.push(span.innerHTML);
28 wrap = true;
29 break;
30
31 default:
32 repl.push('');
33 }
34 }
35 else {
36 repl.push(arguments[i]);
37 }
38 }
39
40 var rv = fmt.format.apply(fmt, repl);
41 return wrap ? E('span', rv) : rv;
42 }
43
44 function forward_proto_txt(s) {
45 return fmt('%s-%s',
46 fwtool.fmt_family(uci.get('firewall', s, 'family')),
47 fwtool.fmt_proto(uci.get('firewall', s, 'proto'),
48 uci.get('firewall', s, 'icmp_type')) || 'TCP+UDP');
49 }
50
51 function forward_src_txt(s) {
52 var z = fwtool.fmt_zone(uci.get('firewall', s, 'src'), _('any zone')),
53 a = fwtool.fmt_ip(uci.get('firewall', s, 'src_ip'), _('any host')),
54 p = fwtool.fmt_port(uci.get('firewall', s, 'src_port')),
55 m = fwtool.fmt_mac(uci.get('firewall', s, 'src_mac'));
56
57 if (p && m)
58 return fmt(_('From %s in %s with source %s and %s'), a, z, p, m);
59 else if (p || m)
60 return fmt(_('From %s in %s with source %s'), a, z, p || m);
61 else
62 return fmt(_('From %s in %s'), a, z);
63 }
64
65 function forward_via_txt(s) {
66 var a = fwtool.fmt_ip(uci.get('firewall', s, 'src_dip'), _('any router IP')),
67 p = fwtool.fmt_port(uci.get('firewall', s, 'src_dport'));
68
69 if (p)
70 return fmt(_('Via %s at %s'), a, p);
71 else
72 return fmt(_('Via %s'), a);
73 }
74
75 return L.view.extend({
76 callHostHints: rpc.declare({
77 object: 'luci',
78 method: 'host_hints'
79 }),
80
81 load: function() {
82 return Promise.all([
83 this.callHostHints()
84 ]);
85 },
86
87 render: function(data) {
88 var hosts = data[0],
89 m, s, o;
90
91 m = new form.Map('firewall', _('Firewall - Port Forwards'),
92 _('Port forwarding allows remote computers on the Internet to connect to a specific computer or service within the private LAN.'));
93
94 s = m.section(form.GridSection, 'redirect', _('Port Forwards'));
95 s.addremove = true;
96 s.anonymous = true;
97 s.sortable = true;
98
99 s.tab('general', _('General Settings'));
100 s.tab('advanced', _('Advanced Settings'));
101
102 s.filter = function(section_id) {
103 return (uci.get('firewall', section_id, 'target') != 'SNAT');
104 };
105
106 s.sectiontitle = function(section_id) {
107 return uci.get('firewall', section_id, 'name') || _('Unnamed forward');
108 };
109
110 o = s.taboption('general', form.Value, 'name', _('Name'));
111 o.placeholder = _('Unnamed forward');
112 o.modalonly = true;
113
114 o = s.option(form.DummyValue, '_match', _('Match'));
115 o.modalonly = false;
116 o.textvalue = function(s) {
117 return E('small', [
118 forward_proto_txt(s), E('br'),
119 forward_src_txt(s), E('br'),
120 forward_via_txt(s)
121 ]);
122 };
123
124 o = s.option(form.ListValue, '_dest', _('Forward to'));
125 o.modalonly = false;
126 o.textvalue = function(s) {
127 var z = fwtool.fmt_zone(uci.get('firewall', s, 'dest'), _('any zone')),
128 a = fwtool.fmt_ip(uci.get('firewall', s, 'dest_ip'), _('any host')),
129 p = fwtool.fmt_port(uci.get('firewall', s, 'dest_port')) ||
130 fwtool.fmt_port(uci.get('firewall', s, 'src_dport'));
131
132 if (p)
133 return fmt(_('%s, %s in %s'), a, p, z);
134 else
135 return fmt(_('%s in %s'), a, z);
136 };
137
138 o = s.option(form.Flag, 'enabled', _('Enable'));
139 o.modalonly = false;
140 o.default = o.enabled;
141 o.editable = true;
142
143 o = s.taboption('general', form.Value, 'proto', _('Protocol'));
144 o.modalonly = true;
145 o.default = 'tcp udp';
146 o.value('tcp udp', 'TCP+UDP');
147 o.value('tcp', 'TCP');
148 o.value('udp', 'UDP');
149 o.value('icmp', 'ICMP');
150
151 o.cfgvalue = function(/* ... */) {
152 var v = this.super('cfgvalue', arguments);
153 return (v == 'tcpudp') ? 'tcp udp' : v;
154 };
155
156 o = s.taboption('general', widgets.ZoneSelect, 'src', _('Source zone'));
157 o.modalonly = true;
158 o.rmempty = false;
159 o.nocreate = true;
160 o.default = 'wan';
161
162 o = s.taboption('advanced', form.Value, 'src_mac', _('Source MAC address'),
163 _('Only match incoming traffic from these MACs.'));
164 o.modalonly = true;
165 o.rmempty = true;
166 o.datatype = 'neg(macaddr)';
167 o.placeholder = E('em', _('any'));
168 L.sortedKeys(hosts).forEach(function(mac) {
169 o.value(mac, '%s (%s)'.format(
170 mac,
171 hosts[mac].name || hosts[mac].ipv4 || hosts[mac].ipv6 || '?'
172 ));
173 });
174
175 o = s.taboption('advanced', form.Value, 'src_ip', _('Source IP address'),
176 _('Only match incoming traffic from this IP or range.'));
177 o.modalonly = true;
178 o.rmempty = true;
179 o.datatype = 'neg(ipmask4)';
180 o.placeholder = E('em', _('any'));
181 L.sortedKeys(hosts, 'ipv4', 'addr').forEach(function(mac) {
182 o.value(hosts[mac].ipv4, '%s (%s)'.format(
183 hosts[mac].ipv4,
184 hosts[mac].name || mac
185 ));
186 });
187
188 o = s.taboption('advanced', form.Value, 'src_port', _('Source port'),
189 _('Only match incoming traffic originating from the given source port or port range on the client host'));
190 o.modalonly = true;
191 o.rmempty = true;
192 o.datatype = 'neg(portrange)';
193 o.placeholder = _('any');
194 o.depends('proto', 'tcp');
195 o.depends('proto', 'udp');
196 o.depends('proto', 'tcp udp');
197 o.depends('proto', 'tcpudp');
198
199 o = s.taboption('advanced', form.Value, 'src_dip', _('External IP address'),
200 _('Only match incoming traffic directed at the given IP address.'));
201 o.modalonly = true;
202 o.rmempty = true;
203 o.datatype = 'neg(ipmask4)';
204 o.placeholder = E('em', _('any'));
205 L.sortedKeys(hosts, 'ipv4', 'addr').forEach(function(mac) {
206 o.value(hosts[mac].ipv4, '%s (%s)'.format(
207 hosts[mac].ipv4,
208 hosts[mac].name || mac
209 ));
210 });
211
212 o = s.taboption('general', form.Value, 'src_dport', _('External port'),
213 _('Match incoming traffic directed at the given destination port or port range on this host'));
214 o.modalonly = true;
215 o.rmempty = false;
216 o.datatype = 'neg(portrange)';
217 o.depends('proto', 'tcp');
218 o.depends('proto', 'udp');
219 o.depends('proto', 'tcp udp');
220 o.depends('proto', 'tcpudp');
221
222 o = s.taboption('general', widgets.ZoneSelect, 'dest', _('Internal zone'));
223 o.modalonly = true;
224 o.rmempty = true;
225 o.nocreate = true;
226 o.default = 'lan';
227
228 o = s.taboption('general', form.Value, 'dest_ip', _('Internal IP address'),
229 _('Redirect matched incoming traffic to the specified internal host'));
230 o.modalonly = true;
231 o.rmempty = true;
232 o.datatype = 'ipmask4';
233 L.sortedKeys(hosts, 'ipv4', 'addr').forEach(function(mac) {
234 o.value(hosts[mac].ipv4, '%s (%s)'.format(
235 hosts[mac].ipv4,
236 hosts[mac].name || mac
237 ));
238 });
239
240 o = s.taboption('general', form.Value, 'dest_port', _('Internal port'),
241 _('Redirect matched incoming traffic to the given port on the internal host'));
242 o.modalonly = true;
243 o.rmempty = true;
244 o.placeholder = _('any');
245 o.datatype = 'portrange';
246 o.depends('proto', 'tcp');
247 o.depends('proto', 'udp');
248 o.depends('proto', 'tcp udp');
249 o.depends('proto', 'tcpudp');
250
251 o = s.taboption('advanced', form.Flag, 'reflection', _('Enable NAT Loopback'));
252 o.modalonly = true;
253 o.rmempty = true;
254 o.default = o.enabled;
255
256 o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'),
257 _('Passes additional arguments to iptables. Use with care!'));
258 o.modalonly = true;
259 o.rmempty = true;
260
261 return m.render();
262 }
263 });