mirror of
https://github.com/webmin/webmin.git
synced 2025-07-23 00:30:33 +00:00
217 lines
5.1 KiB
Perl
Executable File
217 lines
5.1 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
# Update one NAT rule
|
|
|
|
require './ipfilter-lib.pl';
|
|
&ReadParse();
|
|
$rules = &get_ipnat_config();
|
|
if (!$in{'new'}) {
|
|
# Get the rule
|
|
$rule = $rules->[$in{'idx'}];
|
|
}
|
|
else {
|
|
$rule = { 'file' => $config{'ipnat_conf'},
|
|
'type' => 'ipnat' };
|
|
}
|
|
|
|
if ($in{'delete'}) {
|
|
# Just deleting
|
|
&lock_file($rule->{'file'});
|
|
&delete_rule($rule);
|
|
&flush_file_lines();
|
|
&unlock_file($rule->{'file'});
|
|
&webmin_log("delete", "nat", undef, $rule);
|
|
&redirect("");
|
|
exit;
|
|
}
|
|
|
|
# Validate and store inputs, starting with action
|
|
&error_setup($text{'nat_err'});
|
|
$rule->{'cmt'} = $in{'cmt'};
|
|
$rule->{'active'} = $in{'active'};
|
|
$rule->{'action'} = $in{'action'};
|
|
|
|
if ($rule->{'action'} ne 'rdr') {
|
|
# Parse source options
|
|
$rule->{'iface'} = &parse_interface_choice("iface", $text{'nat_eiface'});
|
|
if ($in{'frommode'} == 0) {
|
|
delete($rule->{'from'});
|
|
&parse_ipmask_input("from");
|
|
}
|
|
else {
|
|
$in{'action'} eq 'map-block' && &error($text{'nat_emapblock1'});
|
|
$rule->{'from'} = 1;
|
|
&parse_object_input($rule, "from");
|
|
&parse_object_input($rule, "fromto");
|
|
}
|
|
|
|
# Parse destination
|
|
delete($rule->{'tostart'});
|
|
if ($in{'tomode'} == 0) {
|
|
&parse_ipmask_input("to");
|
|
}
|
|
elsif ($in{'tomode'} == 2) {
|
|
$rule->{'toip'} = '0.0.0.0';
|
|
$rule->{'tomask'} = 32;
|
|
}
|
|
else {
|
|
$in{'action'} eq 'map-block' && &error($text{'nat_emapblock2'});
|
|
&check_ipaddress($in{'tostart'}) ||
|
|
&error($text{'nat_etostart'});
|
|
&check_ipaddress($in{'toend'}) ||
|
|
&error($text{'nat_etoend'});
|
|
$rule->{'tostart'} = $in{'tostart'};
|
|
$rule->{'toend'} = $in{'toend'};
|
|
}
|
|
|
|
# Parse port mapping
|
|
if ($in{'portmapmode'} == 0) {
|
|
delete($rule->{'portmap'});
|
|
}
|
|
else {
|
|
$rule->{'portmap'} = $in{'portmap'};
|
|
if ($in{'portmapnoauto'}) {
|
|
$rule->{'portauto'} = 0;
|
|
&valid_port($in{'portmapfrom'}) ||
|
|
&error($text{'nat_eportmapfrom'});
|
|
&valid_port($in{'portmapto'}) ||
|
|
&error($text{'nat_eportmapto'});
|
|
$rule->{'portmapfrom'} = $in{'portmapfrom'};
|
|
$rule->{'portmapto'} = $in{'portmapto'};
|
|
}
|
|
else {
|
|
$rule->{'portauto'} = 1;
|
|
}
|
|
}
|
|
|
|
# Parse application proxy
|
|
if ($in{'proxymode'} == 0) {
|
|
delete($rule->{'proxyport'});
|
|
}
|
|
else {
|
|
&parse_proxy_input("proxy");
|
|
}
|
|
|
|
# Parse other options
|
|
if ($in{'proto'}) {
|
|
$rule->{'proto'} = $in{'protoproto'};
|
|
}
|
|
else {
|
|
delete($rule->{'proto'});
|
|
}
|
|
$rule->{'frag'} = $in{'frag'};
|
|
if ($in{'mssclamp'}) {
|
|
$in{'mss'} =~ /^\d+$/ || &error($text{'nat_emss'});
|
|
$rule->{'mssclamp'} = $in{'mss'};
|
|
}
|
|
else {
|
|
delete($rule->{'mssclamp'});
|
|
}
|
|
if ($in{'oproxy'}) {
|
|
&parse_proxy_input("oproxy");
|
|
}
|
|
else {
|
|
delete($rule->{'oproxyport'});
|
|
}
|
|
}
|
|
else {
|
|
# Validate and store redirect inputs
|
|
$rule->{'iface'} = &parse_interface_choice("iface", $text{'nat_eiface'});
|
|
|
|
# Save redirect address
|
|
&parse_ipmask_input("from");
|
|
|
|
# Save destination ports
|
|
if ($in{'dportsmode'} == 0) {
|
|
&valid_port($in{'dport'}) || &error($text{'nat_edport'});
|
|
$rule->{'dport1'} = $in{'dport'};
|
|
delete($rule->{'dport2'});
|
|
}
|
|
else {
|
|
&valid_port($in{'dport1'}) || &error($text{'nat_edport1'});
|
|
&valid_port($in{'dport2'}) || &error($text{'nat_edport2'});
|
|
$rule->{'dport1'} = $in{'dport1'};
|
|
$rule->{'dport2'} = $in{'dport2'};
|
|
}
|
|
|
|
# Save protocol
|
|
$rule->{'rdrproto'} = $in{'rdrproto'};
|
|
|
|
# Save redirect IPs
|
|
@ips = split(/\s+/, $in{'rdrip'});
|
|
foreach $ip (@ips) {
|
|
&check_ipaddress($ip) || &error(&text('net_erdrip', $ip));
|
|
}
|
|
@ips || &error($text{'nat_erdrips'});
|
|
$rule->{'rdrip'} = \@ips;
|
|
|
|
# Save redirect port
|
|
&valid_port($in{'rdrport'}) || &error($text{'nat_erdrport'});
|
|
$rule->{'rdrport'} = $in{'rdrport'};
|
|
|
|
# Save options
|
|
$rule->{'round-robin'} = $in{'round-robin'};
|
|
$rule->{'frag'} = $in{'frag'};
|
|
if ($in{'mssclamp'}) {
|
|
$in{'mss'} =~ /^\d+$/ || &error($text{'nat_emss'});
|
|
$rule->{'mssclamp'} = $in{'mss'};
|
|
}
|
|
else {
|
|
delete($rule->{'mssclamp'});
|
|
}
|
|
}
|
|
|
|
&lock_file($rule->{'file'});
|
|
if ($in{'new'}) {
|
|
if ($in{'before'} ne '') {
|
|
# Insert before some rule
|
|
$before = $rules->[$in{'before'}];
|
|
&insert_rule($rule, $before);
|
|
}
|
|
elsif ($in{'after'} ne '') {
|
|
if ($in{'after'} == @$rules - 1) {
|
|
&create_rule($rule); # at end anyway
|
|
}
|
|
else {
|
|
# Insert after some rule
|
|
$before = $rules->[$in{'after'}+1];
|
|
&insert_rule($rule, $before);
|
|
}
|
|
}
|
|
else {
|
|
# Append to end
|
|
&create_rule($rule);
|
|
}
|
|
}
|
|
else {
|
|
&modify_rule($rule);
|
|
}
|
|
&flush_file_lines();
|
|
&unlock_file($rule->{'file'});
|
|
©_to_cluster();
|
|
&webmin_log($in{'new'} ? "create" : "modify", "nat", undef, $rule);
|
|
|
|
&redirect("");
|
|
|
|
# parse_ipmask_input(prefix)
|
|
sub parse_ipmask_input
|
|
{
|
|
local ($pfx) = @_;
|
|
&check_ipaddress($in{$pfx."ip"}) || &error($text{'nat_e'.$pfx.'ip'});
|
|
&check_ipaddress($in{$pfx."mask"}) ||
|
|
$in{$pfx."mask"} =~ /^\d+$/ &&
|
|
$in{$pfx."mask"} >= 0 && $in{$pfx."mask"} <= 32 ||
|
|
&error($text{'nat_e'.$pfx.'ip'});
|
|
$rule->{$pfx."ip"} = $in{$pfx."ip"};
|
|
$rule->{$pfx."mask"} = $in{$pfx."mask"};
|
|
}
|
|
|
|
sub parse_proxy_input
|
|
{
|
|
local ($pfx) = @_;
|
|
&valid_port($in{$pfx."port"}) || &error($text{'nat_e'.$pfx.'port'});
|
|
&valid_port($in{$pfx."name"}) || &error($text{'nat_e'.$pfx.'name'});
|
|
$rule->{$pfx."port"} = $in{$pfx."port"};
|
|
$rule->{$pfx."name"} = $in{$pfx."name"};
|
|
$rule->{$pfx."proto"} = $in{$pfx."proto"};
|
|
}
|