2020-01-03 19:16:11 +00:00
'use strict' ;
'require ui' ;
'require rpc' ;
'require uci' ;
'require form' ;
'require tools.firewall as fwtool' ;
'require tools.widgets as widgets' ;
function fmt ( fmt /*, ...*/ ) {
var repl = [ ] , wrap = false ;
for ( var i = 1 ; i < arguments . length ; i ++ ) {
if ( L . dom . elem ( arguments [ i ] ) ) {
switch ( arguments [ i ] . nodeType ) {
case 1 :
repl . push ( arguments [ i ] . outerHTML ) ;
wrap = true ;
break ;
case 3 :
repl . push ( arguments [ i ] . data ) ;
break ;
case 11 :
var span = E ( 'span' ) ;
span . appendChild ( arguments [ i ] ) ;
repl . push ( span . innerHTML ) ;
wrap = true ;
break ;
default :
repl . push ( '' ) ;
}
}
else {
repl . push ( arguments [ i ] ) ;
}
}
var rv = fmt . format . apply ( fmt , repl ) ;
return wrap ? E ( 'span' , rv ) : rv ;
}
function snat _proto _txt ( s ) {
return fmt ( '%s-%s' ,
fwtool . fmt _family ( uci . get ( 'firewall' , s , 'family' ) ) ,
fwtool . fmt _proto ( uci . get ( 'firewall' , s , 'proto' ) ,
uci . get ( 'firewall' , s , 'icmp_type' ) ) || 'TCP+UDP' ) ;
}
function snat _src _txt ( s ) {
var z = fwtool . fmt _zone ( uci . get ( 'firewall' , s , 'src' ) , _ ( 'any zone' ) ) ,
a = fwtool . fmt _ip ( uci . get ( 'firewall' , s , 'src_ip' ) , _ ( 'any host' ) ) ,
p = fwtool . fmt _port ( uci . get ( 'firewall' , s , 'src_port' ) ) ,
m = fwtool . fmt _mac ( uci . get ( 'firewall' , s , 'src_mac' ) ) ;
if ( p && m )
return fmt ( _ ( 'From %s in %s with source %s and %s' ) , a , z , p , m ) ;
else if ( p || m )
return fmt ( _ ( 'From %s in %s with source %s' ) , a , z , p || m ) ;
else
return fmt ( _ ( 'From %s in %s' ) , a , z ) ;
}
function snat _via _txt ( s ) {
var a = fwtool . fmt _ip ( uci . get ( 'firewall' , s , 'src_dip' ) , _ ( 'any router IP' ) ) ,
p = fwtool . fmt _port ( uci . get ( 'firewall' , s , 'src_dport' ) ) ;
if ( p )
return fmt ( _ ( 'Via %s at %s' ) , a , p ) ;
else
return fmt ( _ ( 'Via %s' ) , a ) ;
}
return L . view . extend ( {
callHostHints : rpc . declare ( {
object : 'luci-rpc' ,
method : 'getHostHints' ,
expect : { '' : { } }
} ) ,
load : function ( ) {
return Promise . all ( [
this . callHostHints ( )
] ) ;
} ,
render : function ( data ) {
var hosts = data [ 0 ] ,
m , s , o ;
m = new form . Map ( 'firewall' , _ ( 'Firewall - Source NAT' ) ,
_ ( 'Source NAT is a specific form of masquerading which allows fine grained control over the source IP used for outgoing traffic, for example to map multiple WAN addresses to internal subnets.' ) ) ;
2020-01-04 10:27:39 +00:00
s = m . section ( form . GridSection , 'redirect' , _ ( 'Port SNAT' ) ) ;
2020-01-03 19:16:11 +00:00
s . addremove = true ;
s . anonymous = true ;
s . sortable = true ;
s . tab ( 'general' , _ ( 'General Settings' ) ) ;
s . tab ( 'advanced' , _ ( 'Advanced Settings' ) ) ;
s . filter = function ( section _id ) {
return ( uci . get ( 'firewall' , section _id , 'target' ) != 'DNAT' ) ;
} ;
s . sectiontitle = function ( section _id ) {
return uci . get ( 'firewall' , section _id , 'name' ) || _ ( 'Unnamed snat' ) ;
} ;
s . handleAdd = function ( ev ) {
var config _name = this . uciconfig || this . map . config ,
section _id = uci . add ( config _name , this . sectiontype ) ;
uci . set ( config _name , section _id , 'target' , 'SNAT' ) ;
this . addedSection = section _id ;
this . renderMoreOptionsModal ( section _id ) ;
} ;
o = s . taboption ( 'general' , form . Value , 'name' , _ ( 'Name' ) ) ;
o . placeholder = _ ( 'Unnamed snat' ) ;
o . modalonly = true ;
o = s . option ( form . DummyValue , '_match' , _ ( 'Match' ) ) ;
o . modalonly = false ;
o . textvalue = function ( s ) {
return E ( 'small' , [
snat _proto _txt ( s ) , E ( 'br' ) ,
snat _src _txt ( s ) , E ( 'br' ) ,
snat _via _txt ( s )
] ) ;
} ;
o = s . option ( form . ListValue , '_dest' , _ ( 'snat to' ) ) ;
o . modalonly = false ;
o . textvalue = function ( s ) {
var z = fwtool . fmt _zone ( uci . get ( 'firewall' , s , 'dest' ) , _ ( 'any zone' ) ) ,
a = fwtool . fmt _ip ( uci . get ( 'firewall' , s , 'dest_ip' ) , _ ( 'any host' ) ) ,
p = fwtool . fmt _port ( uci . get ( 'firewall' , s , 'dest_port' ) ) ||
fwtool . fmt _port ( uci . get ( 'firewall' , s , 'src_dport' ) ) ;
if ( p )
return fmt ( _ ( '%s, %s in %s' ) , a , p , z ) ;
else
return fmt ( _ ( '%s in %s' ) , a , z ) ;
} ;
o = s . option ( form . Flag , 'enabled' , _ ( 'Enable' ) ) ;
o . modalonly = false ;
o . default = o . enabled ;
o . editable = true ;
o = s . taboption ( 'general' , form . Value , 'proto' , _ ( 'Protocol' ) ) ;
o . modalonly = true ;
o . default = 'tcp udp' ;
o . value ( 'tcp udp' , 'TCP+UDP' ) ;
o . value ( 'tcp' , 'TCP' ) ;
o . value ( 'udp' , 'UDP' ) ;
o . value ( 'icmp' , 'ICMP' ) ;
o . cfgvalue = function ( /* ... */ ) {
var v = this . super ( 'cfgvalue' , arguments ) ;
return ( v == 'tcpudp' ) ? 'tcp udp' : v ;
} ;
o = s . taboption ( 'general' , widgets . ZoneSelect , 'src' , _ ( 'Source zone' ) ) ;
o . modalonly = true ;
o . rmempty = false ;
o . nocreate = true ;
o . default = 'wan' ;
o = s . taboption ( 'advanced' , form . Value , 'src_ip' , _ ( 'Source IP address' ) ,
_ ( 'Only match incoming traffic from this IP or range.' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . datatype = 'neg(ipmask4)' ;
o . placeholder = E ( 'em' , _ ( 'any' ) ) ;
L . sortedKeys ( hosts , 'ipv4' , 'addr' ) . forEach ( function ( mac ) {
o . value ( hosts [ mac ] . ipv4 , '%s (%s)' . format (
hosts [ mac ] . ipv4 ,
hosts [ mac ] . name || mac
) ) ;
} ) ;
o = s . taboption ( 'advanced' , form . Value , 'src_port' , _ ( 'Source port' ) ,
_ ( 'Only match incoming traffic originating from the given source port or port range on the client host' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . datatype = 'neg(portrange)' ;
o . placeholder = _ ( 'any' ) ;
o . depends ( 'proto' , 'tcp' ) ;
o . depends ( 'proto' , 'udp' ) ;
o . depends ( 'proto' , 'tcp udp' ) ;
o . depends ( 'proto' , 'tcpudp' ) ;
o = s . taboption ( 'general' , widgets . ZoneSelect , 'dest' , _ ( 'Destination zone' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . nocreate = true ;
o . default = 'lan' ;
o = s . taboption ( 'general' , form . Value , 'dest_ip' , _ ( 'Destination IP address' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . datatype = 'ipmask4' ;
L . sortedKeys ( hosts , 'ipv4' , 'addr' ) . forEach ( function ( mac ) {
o . value ( hosts [ mac ] . ipv4 , '%s (%s)' . format (
hosts [ mac ] . ipv4 ,
hosts [ mac ] . name || mac
) ) ;
} ) ;
o = s . taboption ( 'general' , form . Value , 'dest_port' , _ ( 'Destination port' ) ,
_ ( 'Match forwarded traffic to the given destination or port range' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . placeholder = _ ( 'any' ) ;
o . datatype = 'portrange' ;
o . depends ( 'proto' , 'tcp' ) ;
o . depends ( 'proto' , 'udp' ) ;
o . depends ( 'proto' , 'tcp udp' ) ;
o . depends ( 'proto' , 'tcpudp' ) ;
o = s . taboption ( 'general' , form . Value , 'src_dip' , _ ( 'SNAT IP address' ) ,
_ ( 'Rewrite matched traffic to the given address' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . datatype = 'ipmask4' ;
L . sortedKeys ( hosts , 'ipv4' , 'addr' ) . forEach ( function ( mac ) {
o . value ( hosts [ mac ] . ipv4 , '%s (%s)' . format (
hosts [ mac ] . ipv4 ,
hosts [ mac ] . name || mac
) ) ;
} ) ;
o = s . taboption ( 'general' , form . Value , 'src_dport' , _ ( 'SNAT port' ) ,
_ ( 'Rewrite matched traffic to the given source port. May be left empty to only rewrite the IP address' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
o . placeholder = _ ( 'Do not rewrite' ) ;
o . datatype = 'portrange' ;
o . depends ( 'proto' , 'tcp' ) ;
o . depends ( 'proto' , 'udp' ) ;
o . depends ( 'proto' , 'tcp udp' ) ;
o . depends ( 'proto' , 'tcpudp' ) ;
o = s . taboption ( 'advanced' , form . Value , 'extra' , _ ( 'Extra arguments' ) ,
_ ( 'Passes additional arguments to iptables. Use with care!' ) ) ;
o . modalonly = true ;
o . rmempty = true ;
return m . render ( ) ;
}
} ) ;