) {
s/\r|\n//g;
if ($_ =~ /\??FORMAT\s+2/) {
return 1;
}
}
close(FILE);
}
return 0;
}
sub interfaces_row
{
if (&new_interfaces_format()) {
return ( $_[1],
$_[0] eq '-' ? $text{'list_any'} : $_[0],
$_[2] eq '-' || $_[2] eq '' ? $text{'list_none'} : $_[2] );
}
else {
return ( $_[1],
$_[0] eq '-' ? $text{'list_any'} : $_[0],
$_[2] eq 'detect' ? $text{'list_auto'} :
$_[2] eq '-' || $_[2] eq '' ? $text{'list_none'} : $_[2],
$_[3] eq '-' || $_[3] eq '' ? $text{'list_none'} : $_[3] );
}
}
@interfaces_opts = ( 'dhcp', 'multi', 'routefilter',
'maclist', 'tcpflags', 'proxyarp' );
if (!&version_atleast(5, 0, 4)) {
push(@interfaces_opts, 'noping', 'filterping', 'routestopped',
'norfc1918', 'dropunclean', 'logunclean', 'blacklist');
}
if (&version_atleast(3)) {
push(@interfaces_opts, "logmartians", "routeback", "arp_filter",
"arp_ignore", "nosmurfs", "detectnets", "upnp");
}
sub interfaces_form
{
print " | $text{'interfaces_0'} | \n";
print " | \n";
local @ztable = &read_table_file("zones", \&zones_parser);
print "$text{'interfaces_1'} | \n";
print "\n";
&zone_field("zone", $_[0], 0, 1);
print " |
\n";
if (&new_interfaces_format()) {
local %opts = map { $_, 1 } split(/,/, $_[2]);
print " | $text{'interfaces_3'} | \n";
&options_input("opts", $_[2], \@interfaces_opts);
print " |
\n";
}
else {
local $bmode = $_[2] eq 'detect' ? 2 :
$_[2] eq '-' || $_[2] eq '' ? 1 : 0;
print " | $text{'interfaces_2'} | \n";
printf " %s\n",
$bmode == 1 ? "checked" : "", $text{'list_none'};
printf " %s\n",
$bmode == 2 ? "checked" : "", $text{'list_auto'};
printf "\n",
$bmode == 0 ? "checked" : "";
printf " |
\n",
$bmode == 0 ? $_[2] : "";
local %opts = map { $_, 1 } split(/,/, $_[3]);
print " | $text{'interfaces_3'} | \n";
&options_input("opts", $_[3], \@interfaces_opts);
print " |
\n";
}
}
sub interfaces_validate
{
$in{'iface'} =~ /^[a-z]+\d*(s\d*)?(\.\d+)?$/ ||
$in{'iface'} =~ /^[a-z]+\+$/ || &error($text{'interfaces_eiface'});
local @result = ( $in{'zone'}, $in{'iface'});
if (not &new_interfaces_format()) {
$in{'broad_mode'} || $in{'broad'} =~ /^[0-9\.,]+$/ ||
&error($text{'interfaces_ebroad'});
push(@result, $in{'broad_mode'} == 2 ? 'detect' :
$in{'broad_mode'} == 1 ? '-' : $in{'broad'});
}
push(@result, join(",", split(/\0/, $in{'opts'})));
return @result;
}
sub interfaces_columns
{
return &new_interfaces_format() ? 3 : 4;
}
sub interfaces_colnames
{
local @result = (
$text{'interfaces_0'},
$text{'interfaces_1'} );
if (not &new_interfaces_format()) {
push(@result, $text{'interfaces_2'});
}
push(@result, $text{'interfaces_3'});
return @result;
}
################################# policy #######################################
sub policy_row
{
return ( $_[0] eq 'all' ? $text{'list_any'} :
&is_fw($_[0]) ? $text{'list_fw'} : $_[0],
$_[1] eq 'all' ? $text{'list_any'} :
&is_fw($_[1]) ? $text{'list_fw'} : $_[1],
$_[2], $_[3] eq '-' || $_[3] eq '' ? $text{'list_none'} : $_[3],
$_[4] =~ /(\d+):(\d+)/ ? &text('policy_limit', "$1", "$2")
: $text{'list_none'} );
}
@policy_list = ( "ACCEPT", "DROP", "REJECT", "CONTINUE" );
sub policy_form
{
local $found;
print " | $text{'policy_0'} | \n";
print "\n";
&zone_field("source", $_[0], 0);
print " | \n";
print "$text{'policy_1'} | \n";
print "\n";
&zone_field("dest", $_[1], 0);
print " |
\n";
print " | $text{'policy_2'} | \n";
print " | \n";
print "$text{'policy_3'} | \n";
print " |
\n";
local ($l, $b) = $_[4] =~ /(\d+):(\d+)/ ? ($1, $2) : ( );
print " | $text{'policy_4'} | \n";
printf " %s\n",
$l eq '' ? "checked" : "", $text{'list_none'};
printf "\n",
$l eq '' ? "" : "checked";
print &text('policy_limit',
"",
"")," |
\n";
}
sub policy_validate
{
&is_fw($in{'source'}) && &is_fw($in{'dest'}) && &error($text{'policy_efw'});
if (!$in{'limit_def'}) {
$in{'limit'} =~ /^\d+$/ || &error($text{'policy_elimit'});
$in{'burst'} =~ /^\d+$/ || &error($text{'policy_eburst'});
}
return ( $in{'source'}, $in{'dest'}, $in{'policy'}, $in{'log'},
$in{'limit_def'} ? ( ) : ( "$in{'limit'}:$in{'burst'}" ) );
}
################################# rules #######################################
sub rules_row
{
return ( $_[0] =~ /^(\S+):/ ? "$1" : $_[0],
&is_fw($_[1]) ? $text{'list_fw'} :
$_[1] eq 'all' ? $text{'list_any'} :
$config{'display_zone_descriptions'} == 0 ? $_[1] :
$_[1] =~ /^([^:]+):(\S+)$/ ?
&text('rules_hosts', &convert_zone("$1"), &nice_host_list("$2")) :
&text('rules_zone', &convert_zone($_[1])),
&is_fw($_[2]) ? $text{'list_fw'} :
$_[2] eq 'all' ? $text{'list_any'} :
$_[2] =~ /^\d+$/ ? &text('rules_rport', $_[2]) :
$config{'display_zone_descriptions'} == 0 ? $_[2] :
$_[2] =~ /^([^:]+):(\S+)$/ ?
&text('rules_hosts', &convert_zone("$1"), &nice_host_list("$2")) :
&text('rules_zone', &convert_zone($_[2])),
$_[3] eq 'all' ? $text{'list_any'} :
$_[3] eq 'related' ? $text{'rules_related'} : uc($_[3]),
$_[3] eq 'all' || $_[3] eq 'related' ? "" :
$_[5] eq '-' || $_[5] eq '' ? $text{'list_any'} : $_[5],
$_[4] eq '-' || $_[4] eq '' ? "" : $_[4],
&version_atleast(1, 4, 7) ? (
$_[7] eq "-" ? "" : $_[7],
$_[8] eq "-" ? "" : $_[8] ) :
( )
);
}
@rules_actions = ( 'ACCEPT', 'DROP', 'REJECT', 'DNAT', 'DNAT-', 'REDIRECT' );
if (&version_atleast(2, 0, 0)) {
push(@rules_actions, 'CONTINUE');
push(@rules_actions, 'ACCEPT+');
push(@rules_actions, 'NONAT');
push(@rules_actions, 'REDIRECT-');
push(@rules_actions, 'LOG');
}
if (&version_atleast(3)) {
push(@rules_actions, 'DNAT-');
push(@rules_actions, 'SAME');
push(@rules_actions, 'SAME-');
push(@rules_actions, 'QUEUE');
}
@rules_protos = ( 'all', 'related', 'tcp', 'udp', 'icmp' );
sub rules_form
{
local $found;
local @ztable = &read_table_file("zones", \&zones_parser);
local ($action, $log) = split(/:/, $_[0]);
local $macroarg;
if ($action =~ /^(.*)\/(.*)$/) {
$action = $1;
$macroarg = $2;
}
# Rule action
print " | $text{'rules_0'} | \n";
print "\n";
# Logging level
print "$text{'rules_log'} |
\n";
if (&version_atleast(3)) {
print " | $text{'rules_macro'} | \n";
print "\n";
print &ui_select("macro", $macroarg,
[ [ "", "<$text{'rules_none2'}>" ],
map { [ $_ ] } (sort { $a cmp $b } @rules_actions) ],
1, 0, $macroarg);
print " |
\n";
}
# Source zone and hosts
local ($zone, $host) = split(/:/, $_[1], 2);
print " | $text{'rules_1z'} | \n";
print "\n";
$found = &zone_field("source", $zone, 1);
printf "\n",
$found ? "" : $zone;
print " $text{'rules_inzone'}\n";
printf " %s\n",
$host ? "checked" : "", $text{'rules_addr'};
printf " |
\n",
join(" ", split(/,/, $host));
($zone, $host) = split(/:/, $_[2], 2);
print " | $text{'rules_2z'} | \n";
print "\n";
$found = &zone_field("dest", $zone, 1);
printf "\n",
$found ? "" : $zone;
print " $text{'rules_inzone'}\n";
printf " %s\n",
$host ? "checked" : "", $text{'rules_addr'};
printf "\n",
join(" ", split(/,/, $host));
print " $text{'rules_dnat_dest'} |
\n";
print " | $text{'rules_3'} | \n";
print "\n";
printf " |
\n",
$found ? "" : $_[3];
print " | $text{'rules_4'} | \n";
printf " %s\n",
$_[5] eq '' || $_[5] eq '-' ? "checked" : "", $text{'list_any'};
printf " %s\n",
$_[5] eq '' || $_[5] eq '-' ? "" : "checked", $text{'rules_ranges'};
printf " |
\n",
$_[5] eq '' || $_[5] eq '-' ? "" : join(" ", split(/,/, $_[5]));
print " | $text{'rules_5'} | \n";
printf " %s\n",
$_[4] eq '' || $_[4] eq '-' ? "checked" : "", $text{'list_any'};
printf " %s\n",
$_[4] eq '' || $_[4] eq '-' ? "" : "checked", $text{'rules_ranges'};
printf "\n",
$_[4] eq '' || $_[4] eq '-' ? "" : join(" ", split(/,/, $_[4]));
print " $text{'rules_dnat_port'} |
\n";
print " | $text{'rules_dnat'} | \n";
printf " %s\n",
$_[6] eq '' || $_[6] eq '-' ? "checked" : "", $text{'list_none'};
printf "\n",
$_[6] eq '' || $_[6] eq '-' ? "" : "checked";
printf " |
\n",
$_[6] eq '' || $_[6] eq '-' ? "" : $_[6];
if (&version_atleast(1, 4, 7)) {
print " | $text{'rules_rate'} | \n";
printf " %s\n",
$_[7] eq "-" || !$_[7] ? "checked" : "", $text{'rules_norate'};
printf "\n",
$_[7] eq "-" || !$_[7] ? "" : "checked";
printf " |
\n",
$_[7] eq "-" ? "" : $_[7];
print " | $text{'rules_set'} | \n";
printf " %s\n",
$_[8] eq "-" || !$_[8] ? "checked" : "", $text{'rules_noset'};
printf "\n",
$_[8] eq "-" || !$_[8] ? "" : "checked";
printf " |
\n",
$_[8] eq "-" ? "" : $_[8];
}
}
sub rules_validate
{
$in{'action'} !~ /----/ || &error($text{'rules_eaction'});
$in{'source'} || $in{'sother'} =~ /^\S+$/ || &error($text{'rules_esother'});
!$in{'sinzone_def'} || $in{'sinzone'} =~ /\S/ || &error($text{'rules_esinzone'});
$in{'dest'} || $in{'dother'} =~ /^\S+$/ || &error($text{'rules_edother'});
!$in{'dinzone_def'} || $in{'dinzone'} =~ /\S/ || &error($text{'rules_edinzone'});
$in{'proto'} || $in{'pother'} =~ /^\S+$/ || &error($text{'rules_epother'});
$in{'sport_def'} || $in{'sport'} =~ /\S/ || &error($text{'rules_esport'});
$in{'dport_def'} || $in{'dport'} =~ /\S/ || &error($text{'rules_edport'});
$in{'dnat_def'} || &check_ipaddress($in{'dnat'}) ||
($in{'dnat'} =~ /^([0-9\.]+):([0-9\.]+)$/ &&
&check_ipaddress("$1") && &check_ipaddress("$2")) ||
($in{'dnat'} =~ /^\!([0-9\.]+)$/ && &check_ipaddress("$1")) ||
($in{'dnat'} =~ /^\!([0-9\.]+),([0-9\.]+)(\/\d+)?$/ &&
&check_ipaddress("$1") && &check_ipaddress("$2")) ||
($in{'dnat'} =~ /^\!([0-9\.,]+)$/ &&
scalar(grep { &check_ipaddress($_) } split(/,/, $1))) ||
&error($text{'rules_ednat'});
$in{'action'} ne 'DNAT' && $in{'action'} ne 'REDIRECT' && $in{'action'} ne 'DNAT-' &&
!$in{'dnat_def'} && &error($text{'rules_ednat2'});
$in{'sinzone'} =~ s/\s+/,/g;
$in{'dinzone'} =~ s/\s+/,/g;
$in{'sport'} =~ s/\s+/,/g;
$in{'dport'} =~ s/\s+/,/g;
if (&version_atleast(1, 4, 7)) {
$in{'rate_def'} || $in{'rate'} =~ /^\S+$/ ||
&error($text{'rules_erate'});
$in{'set_def'} || $in{'set'} =~ /^\S+$/ ||
&error($text{'rules_eset'});
}
if ($in{'macro'} && &indexof($in{'action'}, &list_standard_macros()) >= 0) {
$in{'action'} .= "/".$in{'macro'};
$in{'proto'} = $in{'pother'} = undef;
}
return ( $in{'log'} ? "$in{'action'}:$in{'log'}" : $in{'action'},
($in{'source'} || $in{'sother'}).
($in{'sinzone_def'} ? ":$in{'sinzone'}" : ""),
($in{'dest'} || $in{'dother'}).
($in{'dinzone_def'} ? ":$in{'dinzone'}" : ""),
$in{'proto'} || $in{'pother'} || '-',
$in{'dport_def'} ? "-" : $in{'dport'},
$in{'sport_def'} ? "-" : $in{'sport'},
$in{'dnat_def'} ? "-" : $in{'dnat'},
&version_atleast(1, 4, 7) ? (
( $in{'rate_def'} ? "-" : $in{'rate'} ),
( $in{'set_def'} ? "-" : $in{'set'} )
) : ( )
);
}
sub rules_columns
{
return &version_atleast(1, 4, 7) ? 6 : 8;
}
################################# tos #########################################
%tos_map = ( 0, 'Normal-Service',
2, 'Minimize-Cost',
4, 'Maximize-Reliability',
8, 'Maximize-Throughput',
16, 'Minimize-Delay' );
@tos_protos = ( 'tcp', 'udp', 'icmp' );
sub tos_row
{
return ( &is_fw($_[0]) ? $text{'list_fw'} :
$_[0] eq 'all' ? $text{'list_any'} :
$_[0] =~ /^([^:]+):(\S+)$/ ? &text('rules_hosts', "$1", "$2") :
&text('rules_zone', $_[0]),
&is_fw($_[1]) ? $text{'list_fw'} :
$_[1] eq 'all' ? $text{'list_any'} :
$_[1] =~ /^([^:]+):(\S+)$/ ? &text('rules_hosts', "$1", "$2") :
&text('rules_zone', $_[1]),
uc($_[2]),
$_[3] eq '-' || $_[3] eq '' ? $text{'list_any'} : $_[3],
$_[4] eq '-' || $_[4] eq '' ? $text{'list_any'} : $_[4],
$tos_map{$_[5]} || $_[5],
$_[6] eq '-' ? $text{'list_none'} : $_[6] );
}
sub tos_form
{
local ($zone, $host) = split(/:/, $_[0], 2);
print " | $text{'tos_0z'} | \n";
print "\n";
$found = &zone_field("source", $zone, 1);
printf "\n",
$found ? "" : $zone;
print " $text{'rules_inzone'}\n";
printf " %s\n",
$host ? "checked" : "", $text{'rules_addr'};
printf " |
\n",
join(" ", split(/,/, $host));
($zone, $host) = split(/:/, $_[1], 2);
print " | $text{'tos_1z'} | \n";
print "\n";
$found = &zone_field("dest", $zone, 1);
printf "\n",
$found ? "" : $zone;
print " $text{'rules_inzone'}\n";
printf " %s\n",
$host ? "checked" : "", $text{'rules_addr'};
printf " |
\n",
join(" ", split(/,/, $host));
print " | $text{'tos_2'} | \n";
print "\n";
printf " |
\n",
$found ? "" : $_[2];
print " | $text{'tos_3'} | \n";
printf " %s\n",
$_[3] eq '' || $_[3] eq '-' ? "checked" : "", $text{'list_any'};
printf " %s\n",
$_[3] eq '' || $_[3] eq '-' ? "" : "checked", $text{'rules_ranges'};
printf " |
\n",
$_[3] eq '' || $_[3] eq '-' ? "" : join(" ", split(/,/, $_[3]));
print " | $text{'tos_4'} | \n";
printf " %s\n",
$_[4] eq '' || $_[4] eq '-' ? "checked" : "", $text{'list_any'};
printf " %s\n",
$_[4] eq '' || $_[4] eq '-' ? "" : "checked", $text{'rules_ranges'};
printf " |
\n",
$_[4] eq '' || $_[4] eq '-' ? "" : join(" ", split(/,/, $_[4]));
print " | $text{'tos_5'} | \n";
print " |
\n";
print " | $text{'tos_6'} | \n";
printf " |
\n",
$_[6] eq "-" ? "" : $_[6];
}
sub tos_validate
{
$in{'source'} || $in{'sother'} =~ /^\S+$/ || &error($text{'rules_esother'});
!$in{'sinzone_def'} || $in{'sinzone'} =~ /\S/ || &error($text{'rules_esinzone'});
$in{'dest'} || $in{'dother'} =~ /^\S+$/ || &error($text{'rules_edother'});
!$in{'dinzone_def'} || $in{'dinzone'} =~ /\S/ || &error($text{'rules_edinzone'});
$in{'proto'} || $in{'pother'} =~ /^\S+$/ || &error($text{'rules_epother'});
$in{'sport_def'} || $in{'sport'} =~ /\S/ || &error($text{'rules_esport'});
$in{'dport_def'} || $in{'dport'} =~ /\S/ || &error($text{'rules_edport'});
return ( ($in{'source'} || $in{'sother'}).
($in{'sinzone_def'} ? ":$in{'sinzone'}" : ""),
($in{'dest'} || $in{'dother'}).
($in{'dinzone_def'} ? ":$in{'dinzone'}" : ""),
$in{'proto'} || $in{'pother'},
$in{'sport_def'} ? "-" : join(",", split(/\s+/, $in{'sport'})),
$in{'dport_def'} ? "-" : join(",", split(/\s+/, $in{'dport'})),
$in{'tos'},
$in{'mark'} || "-" );
}
################################# masq #########################################
sub masq_row
{
return ( $_[0] =~ /^(\S+):(\S+)$/ ? &text('masq_in', "$1", "$2") : $_[0],
$_[1] =~ /^[0-9\.\/]+$/ ? $_[1] :
$_[1] =~ /^([a-z]+\d*)\!(\S+)$/ ? &text('masq_ex', "$1", "$2") :
&text('masq_iface', $_[1]),
$_[2] eq "" ? "" : $_[2] );
}
sub masq_columns
{
return 3;
}
sub masq_form
{
local ($iface, $net) = split(/:/, $_[0], 2);
print " | $text{'masq_0'} | \n";
&iface_field("iface", $iface);
printf " %s\n",
$net ? "checked" : "", $text{'masq_net'};
print " |
\n";
local ($mnet, $miface, $mode);
if ($_[1] =~ /^[0-9\.\/]+(,[0-9\.\/]+)*$/) {
$mnet = $_[1];
$mode = 0;
}
elsif ($_[1] =~ /^([a-z]+\d*)\!(\S+)$/) {
$miface = $1;
$mnet = $2;
$mode = 1;
}
else {
$miface = $_[1];
$mode = 1;
}
print " | $text{'masq_1'} | \n";
printf " %s\n",
$mode == 0 ? "checked" : "", $text{'masq_mode0'};
printf " \n",
$mode == 0 ? $mnet : "";
printf " %s\n",
$mode == 1 ? "checked" : "", $text{'masq_mode1'};
&iface_field("miface", $mode == 1 ? $miface : undef);
printf " %s\n",
$mode == 1 && $mnet ? "checked" : "", $text{'masq_except'};
printf "\n",
$mode == 1 ? join(" ", split(/,/, $mnet)) : "";
print " |
\n";
print " | $text{'masq_2'} | \n";
printf " %s\n",
$_[2] eq '' || $_[2] eq '-' ? "checked" : "", $text{'list_none'};
printf "\n",
$_[2] eq '' || $_[2] eq '-' ? "" : "checked";
printf " |
\n",
$_[2] eq '' || $_[2] eq '-' ? "" : $_[2];
if (&version_atleast(3)) {
print " | $text{'masq_3'} | \n";
print &ui_radio("proto_def", $_[3] ? 0 : 1,
[ [ 1, $text{'masq_any'} ],
[ 0, " " ] ]),"\n",
&ui_select("proto", $_[3],
[ map { [ $_, uc($_) ] } &list_protocols() ],
1, 0, $_[3] ? 1 : 0)," |
\n";
print " | $text{'masq_4'} | \n";
print &ui_opt_textbox("ports", $_[4], 40, $text{'masq_all'}),
" |
\n";
print " | $text{'masq_5'} | \n";
print &ui_opt_textbox("ipsec", $_[5], 40, $text{'default'}),
" |
\n";
}
}
sub masq_validate
{
!$in{'net_def'} || $in{'net'} =~ /^\S+$/ || &error($text{'masq_enet'});
if ($in{'mode'} == 0) {
$in{'mnet'} =~ /^\S+$/ || &error($text{'masq_emnet'});
}
else {
!$in{'mnet_def'} || $in{'mnete'} =~ /\S/ ||&error($text{'masq_emnete'});
}
$in{'snat_def'} || &check_ipaddress($in{'snat'}) || &error($text{'masq_esnat'});
local @rv = ( $in{'iface'}.(!$in{'net_def'} ? "" : ":$in{'net'}"),
$in{'mode'} == 0 ? $in{'mnet'} :
$in{'miface'}.(!$in{'mnet_def'} ? "" :
"!".join(",", split(/\s+/, $in{'mnete'}))),
$in{'snat_def'} ? ( "" ) : ( $in{'snat'} ) );
if (&version_atleast(3)) {
push(@rv, $in{'proto_def'} ? "" : $in{'proto'});
if ($in{'ports_def'}) {
push(@rv, "");
}
else {
$in{'ports'} =~ /^\S+$/ || &error($text{'masq_eports'});
push(@rv, $in{'ports'});
}
if ($in{'ipsec_def'}) {
push(@rv, "");
}
else {
$in{'ipsec'} =~ /^\S+$/ || &error($text{'masq_eipsec'});
push(@rv, $in{'ipsec'});
}
}
return @rv;
}
################################# nat #########################################
sub nat_form
{
print " | $text{'nat_0'} | \n";
print " | \n";
print "$text{'nat_1'} | \n";
print "";
if (&version_atleast(1, 3, 14)) {
local ($iface, $virt) = split(/:/, $_[1]);
&iface_field("iface", $iface);
print "$text{'nat_virt'}\n";
print "\n";
print " |
\n";
}
else {
&iface_field("iface", $_[1]);
print " \n";
}
print " | $text{'nat_2'} | \n";
print " |
\n";
local $all = $_[3] eq '-' || $_[3] eq '' || $_[3] =~ /yes/i;
print " | $text{'nat_all'} | \n";
printf " %s\n",
$all ? "checked" : "", $text{'yes'};
printf " %s | \n",
$all ? "" : "checked", $text{'no'};
local $local = $_[4] =~ /yes/i;
print "$text{'nat_local'} | \n";
printf " %s\n",
$local ? "checked" : "", $text{'yes'};
printf " %s |
\n",
$local ? "" : "checked", $text{'no'};
}
sub nat_validate
{
&check_ipaddress($in{'ext'}) || &error($text{'nat_eext'});
&check_ipaddress($in{'int'}) || &error($text{'nat_eint'});
$in{'virt'} =~ /^\d*$/ || &error($text{'nat_evirt'});
return ( $in{'ext'},
$in{'virt'} ne '' ? $in{'iface'}.":".$in{'virt'} : $in{'iface'},
$in{'int'},
$in{'all'} ? "yes" : "no",
$in{'local'} ? "yes" : "no" );
}
################################# proxyarp #######################################
sub proxyarp_row
{
return ( $_[0],
$_[1] eq '-' || $_[1] eq '' ? $text{'list_auto'} : $_[1],
$_[2],
&version_atleast(2, 0, 0) ?
( $_[4] =~ /yes/i ? $text{'yes'} : $text{'no'} ) : ( ) );
}
sub proxyarp_form
{
print " | $text{'proxyarp_0'} | \n";
print " | \n";
print "$text{'proxyarp_1'} | \n";
printf " %s\n",
$_[1] eq '-' || $_[1] eq '' ? "checked" : "", $text{'list_auto'};
printf "\n",
$_[1] eq '-' || $_[1] eq '' ? "" : "checked";
&iface_field("int", $_[1] eq '-' ? undef : $_[1]);
print " |
";
local $have = $_[3] =~ /yes/i;
print " | $text{'proxyarp_have'} | \n";
printf " %s\n",
$have ? "checked" : "", $text{'yes'};
printf " %s | \n",
$have ? "" : "checked", $text{'no'};
print "$text{'proxyarp_2'} | \n";
print "";
&iface_field("ext", $_[2]);
print " |
";
if (&version_atleast(2, 0, 0)) {
local $pers = $_[4] =~ /yes/i;
print " | $text{'proxyarp_pers'} | \n";
printf " %s\n",
$pers ? "checked" : "", $text{'yes'};
printf " %s | \n",
$pers ? "" : "checked", $text{'no'};
}
}
sub proxyarp_validate
{
&check_ipaddress($in{'addr'}) || &error($text{'proxyarp_eaddr'});
return ( $in{'addr'},
$in{'int_def'} ? "-" : $in{'int'},
$in{'ext'},
$in{'have'} ? "yes" : "no",
&version_atleast(2, 0, 0) ? ( $in{'pers'} ? "yes" : "no" ) : ( )
);
}
sub proxyarp_columns
{
return &version_atleast(2, 0, 0) ? 4 : 3;
}
################################ routestopped ##################################
sub routestopped_row
{
return ( $_[0], $_[1],
$_[2] eq '-' || $_[2] eq '' ? $text{'default'} : $_[2],
$_[3] eq '-' || $_[3] eq '' ? $text{'tunnels_gnone'} : $_[3] );
}
sub routestopped_columns
{
return 2;
}
@routestopped_options = ( "routeback", "source", "dest", "critical" );
sub routestopped_form
{
print "
| $text{'routestopped_0'} | \n";
print "";
&iface_field("iface", $_[0]);
print " | \n";
local $none = $_[1] eq '' || $_[1] eq '-' || $_[1] eq '0.0.0.0/0';
print "$text{'routestopped_1'} | \n";
printf " %s \n",
$none ? "checked" : "", $text{'routestopped_all'};
printf " %s \n",
$none ? "" : "checked", $text{'routestopped_list'};
print " |
\n";
if (&version_atleast(3)) {
print " | $text{'routestopped_2'} | \n";
print "\n";
&options_input("opts", $_[2], \@routestopped_options);
print " |
\n";
}
}
sub routestopped_validate
{
$in{'addr_def'} || $in{'addr'} =~ /\S/ || &error($text{'routestopped_eaddr'});
return ( $in{'iface'},
$in{'addr_def'} ? "-" : join(",", split(/\s+/, $in{'addr'})),
join(",", split(/\0/, $in{'opts'})) );
}
################################ tunnels ##################################
sub tunnels_row
{
local $tt = $_[0];
$tt =~ s/^(openvpn|generic):.*$/$1/;
return ( $text{'tunnels_'.$tt} || $tt,
$_[1] eq '-' || $_[1] eq '' ? $text{'routestopped_all'} : $_[1],
$_[2], $_[3] );
}
sub tunnels_form
{
print " | $text{'tunnels_0'} | \n";
print "\n";
print "\n";
print " | \n";
print "
| $text{'tunnels_1'} | \n";
print "";
&zone_field("zone", $_[1], 0, 0);
print " |
\n";
local $none = $_[2] eq '' || $_[2] eq '-';
print " | $text{'tunnels_2'} | \n";
printf " %s\n",
$none ? "checked" : "", $text{'default'};
printf " %s\n",
$none ? "" : "checked", $text{'tunnels_sel'};
printf " |
\n", $_[2];
local $none = $_[2] eq '' || $_[2] eq '-';
print " | $text{'tunnels_3'} | \n";
printf " %s\n",
$none ? "checked" : "", $text{'tunnels_gnone'};
printf " %s\n",
$none ? "" : "checked", $text{'tunnels_gsel'};
printf " |
\n",
join(" ", split(/,/, $_[3]));
}
sub tunnels_validate
{
$in{'gateway_def'} || &check_ipaddress($in{'gateway'}) ||
($in{'gateway'} =~ /^(\S+)\/(\d+)$/ && &check_ipaddress($1)) ||
&error($text{'tunnels_egateway'});
if ($in{'type'} eq "openvpn") {
$in{'tport'} =~ /^\d*$/ || &error($text{'tunnels_eopenvpn'});
$in{'type'} .= ":".$in{'tport'} if ($in{'tport'});
}
elsif ($in{'type'} eq 'generic') {
$in{'tport'} =~ /^\S+$/ || &error($text{'tunnels_egeneric'});
$in{'type'} .= ":".$in{'tport'};
}
return ( $in{'type'}, $in{'zone'},
$in{'gateway_def'} ? '-' : $in{'gateway'},
$in{'gzones_def'} ? '-' : join(",", split(/\s+/, $in{'gzones'})) );
}
################################ hosts ##################################
sub hosts_row
{
return ( $_[0], $_[1] =~ /^(\S+):(\S+)$/ ? ( $1, $2 ) : ( undef, undef ) );
}
@host_options = ( "maclist", "routeback" );
if (&version_atleast(3)) {
push(@host_options, "norfc1918", "blacklist", "tcpflags",
"nosmurfs", "ipsec");
}
sub hosts_form
{
print " | $text{'hosts_0'} | \n";
print "";
&zone_field("zone", $_[0], 0, 2);
print " |
\n";
local ($iface, $net) = split(/:/, $_[1]);
print " | $text{'hosts_1'} | \n";
print "";
&iface_field("iface", $iface);
print " |
\n";
print " | $text{'hosts_2'} | \n";
print " |
\n";
print " | $text{'hosts_opts'} | \n";
&options_input("opts", $_[2], \@host_options);
print " |
\n";
}
sub hosts_validate
{
&check_ipaddress($in{'net'}) ||
$in{'net'} =~ /^(\S+)\/(\d+)$/ && &check_ipaddress($1) ||
&error($text{'hosts_enet'});
return ( $in{'zone'}, $in{'iface'}.":".$in{'net'},
join(",", split(/\0/, $in{'opts'})) );
}
################################ blacklist ##################################
sub blacklist_row
{
return ( $_[0] eq '-' ? $text{'blacklist_any'} : $_[0],
uc($_[1]) || $text{'blacklist_any'},
$_[2] || $text{'blacklist_any'} );
}
@blacklist_protos = ( undef, 'tcp', 'udp', 'icmp' );
sub blacklist_form
{
print " | $text{'blacklist_host'} | \n";
local ($mode, $ipset, $mac, $ip);
if ($_[0] =~ /^\+(.*)/) {
$mode = 2; $ipset = $1;
}
elsif ($_[0] =~ /^\~(.*)$/) {
$mode = 1; $mac = $1;
}
elsif ($_[0] eq '-') {
$mode = 3;
}
else {
$mode = 0; $ip = $_[0];
}
print &ui_radio("host_def", $mode,
[ [ 0, &text('hosts_ip', &ui_textbox("host", $ip, 30))." " ],
[ 1, &text('hosts_mac', &ui_textbox("mac", $mac, 30))." " ],
[ 3, $text{'hosts_any'}." " ],
&version_atleast(3) ?
( [ 2, &text('hosts_ipset', &ui_textbox("ipset", $ipset, 15)) ] ) : ( ),
]);
print " |
\n";
print " | $text{'blacklist_proto'} | \n";
print "\n";
printf " |
\n",
$found ? "" : $_[1];
print " | $text{'blacklist_ports'} | \n";
print " |
\n";
}
sub blacklist_validate
{
local $host;
if ($in{'host_def'} == 0) {
&check_ipaddress($in{'host'}) ||
$in{'host'} =~ /^(\S+)\/(\d+)$/ && &check_ipaddress($1) ||
&error($text{'blacklist_ehost'});
$host = $in{'host'};
}
elsif ($in{'host_def'} == 1) {
$in{'mac'} =~ s/:/-/g;
$in{'mac'} =~ /^[0-9a-f]{2}(\-[0-9a-f]{2}){5}$/ ||
&error($text{'blacklist_emac'});
$host = "~".$in{'mac'};
}
elsif ($in{'host_def'} == 2) {
$in{'ipset'} =~ /^\S+$/ || &error($text{'blacklist_eipset'});
$host = "+".$in{'ipset'};
}
elsif ($in{'host_def'} == 3) {
$host = "-";
}
local $proto;
if ($in{'proto'} eq '*') {
$in{'pother'} =~ /^\d+$/ ||
defined(getprotobyname($in{'pother'})) ||
&error($text{'blacklist_eproto'});
$proto = lc($in{'pother'});
}
else {
$proto = lc($in{'proto'});
}
if ($proto eq "tcp" || $proto eq "udp") {
$in{'ports'} =~ /^\S+$/ || &error($text{'blacklist_eports'});
}
elsif ($in{'ports'}) {
&error($text{'blacklist_eports2'});
}
return ( $host, $proto, $in{'ports'} );
}
################################ providers ##################################
sub providers_row
{
return ( $_[0], $_[1], $_[2], $_[4], $_[5] );
}
@providers_opts = ( "track", "balance", "loose" );
sub providers_form
{
print " | $text{'providers_name'} | \n";
print " | \n";
print "$text{'providers_number'} | \n";
print " |
\n";
print " | $text{'providers_iface'} | \n";
print "";
&iface_field("iface", $_[4]);
print " | \n";
print "$text{'providers_mark'} | \n";
print " |
\n";
print " | $text{'providers_gateway'} | \n";
print " | \n";
local $ddef = $_[3] eq "-" || $_[3] eq "" ? 0 : $_[3] eq "main" ? 1 : 2;
print "$text{'providers_dup'} | \n";
print "",&ui_radio("dup_def", $ddef,
[ [ 0, $text{'default'} ],
[ 1, $text{'providers_main'} ],
[ 2, &ui_textbox("dup", $ddef == 2 ? $_[3] : "", 5) ] ]),
" |
\n";
local %opts = map { $_, 1 } split(/,/, $_[6]);
print " | $text{'providers_opts'} | \n";
foreach my $o (@providers_opts) {
print &ui_checkbox("opts", $o, $text{'providers_'.$o}, $opts{$o})." \n";
delete($opts{$o});
}
foreach my $o (keys %opts) {
print &ui_hidden("opts", $o),"\n";
}
print " | \n";
print "$text{'providers_copy'} | \n";
print " |
\n";
}
sub providers_validate
{
$in{'name'} =~ /^\S+$/ || &error($text{'providers_ename'});
$in{'number'} =~ /^\d+$/ || &error($text{'providers_enumber'});
$in{'mark'} =~ /^\d+$/ || &error($text{'providers_emark'});
$in{'dup_def'} < 2 || $in{'dup'} =~ /^\S+$/ || &error($text{'providers_edup'});
&check_ipaddress($in{'gateway'}) || &error($text{'providers_egateway'});
return ( $in{'name'}, $in{'number'}, $in{'mark'},
$in{'dup_def'} == 0 ? '-' : $in{'dup_def'} == 1 ? 'main' : $in{'dup'},
$in{'iface'}, $in{'gateway'},
join(",", split(/\0/, $in{'opts'})) || "-",
$in{'copy'} || "-" );
}
############################## route_rules ################################
sub route_rules_row
{
return ( $_[0] eq "-" ? $text{'list_any'} : $_[0],
$_[1] eq "-" ? $text{'list_any'} : $_[1],
$_[2], $_[3], $_[4] );
}
sub route_rules_form
{
print " | $text{'route_rules_src'} | \n";
print "",&ui_opt_textbox("src", $_[0] eq "-" ? "" : $_[0],
20, $text{'list_any'}, $text{'route_rules_ip'}),
" |
\n";
print " | $text{'route_rules_dst'} | \n";
print "",&ui_opt_textbox("dst", $_[1] eq "-" ? "" : $_[1],
20, $text{'list_any'}, $text{'route_rules_ip'}),
" |
\n";
local @ptable = &read_table_file("providers", \&standard_parser);
print " | $text{'route_rules_prov'} | \n";
print "",&ui_select("prov", $_[2] eq "254" ? "main" : $_[2],
[ [ "main", $text{'route_rules_main'} ],
map { $_->[0] } @ptable ])," |
\n";
print " | $text{'route_rules_pri'} | \n";
print "",&ui_textbox("pri", $_[3], 10)," |
\n";
print " | $text{'route_rules_mark'} | \n";
print "",&ui_opt_textbox("mark", $_[4] eq "-" ? $_[4] : "", 10,
$text{'route_rules_nomark'})," |
\n";
}
sub route_rules_validate
{
$in{'src_def'} || $in{'src'} =~ /^\S+$/ || &error($text{'route_rules_esrc'});
$in{'dst_def'} || $in{'dst'} =~ /^\S+$/ || &error($text{'route_rules_edst'});
$in{'pri'} =~ /^\d+$/ || &error($text{'route_rules_epri'});
$in{'mark_def'} || $in{'mark'} =~ /^\d+(\/\d+)?$/ ||
&error($text{'route_rules_emark'});
return ( $in{'src_def'} ? "-" : $in{'src'},
$in{'dst_def'} ? "-" : $in{'dst'},
$in{'prov'},
$in{'pri'},
$in{'mark_def'} ? ( ) : ( $in{'mark'} ) );
}
################################ shorewall.conf ##################################
sub conf_form
{
local ($msg1, $msg2, $msg3, $field1, $field2, $field3, $dummy) = @_;
$field1 =~ s/"/"/g;
print "| $msg1 | \n";
print " |
\n";
$field2 =~ s/"/"/g;
print "| $msg2 | \n";
print " |
\n";
$field3 =~ s/"/"/g;
print "| $msg3 | \n";
print " |
\n";
print "\n";
}
################################ shorewall.conf ##################################
sub shorewall_conf_columns
{
return 3;
}
sub shorewall_conf_form
{
&conf_form($text{'shorewall_conf_0'}, $text{'shorewall_conf_1'}, $text{'shorewall_conf_2'}, @_);
}
sub shorewall_conf_validate
{
&error($text{'shorewall_conf_varname'}) unless $in{'var'} =~ /^\w+$/;
local $comment = "";
$comment = "\t# ".$in{'comment'} if (exists $in{'comment'} and $in{'comment'} ne "");
return ($in{'var'}.'='.$in{'val'}.$comment);
}
################################ params ##################################
sub params_columns
{
return 3;
}
sub params_form
{
&conf_form($text{'params_0'}, $text{'params_1'}, $text{'params_2'}, @_);
}
sub params_validate
{
&error($text{'params_varname'}) unless $in{'var'} =~ /^\w+$/;
local $comment = "";
$comment = "\t# ".$in{'comment'} if (exists $in{'comment'} and $in{'comment'} ne "");
return ($in{'var'}.'='.$in{'val'}.$comment);
}
#############################################################################
# can_access(file)
sub can_access
{
if ($access{'files'} eq '*') {
return 1;
}
else {
local @acc = split(/\s+/, $access{'files'});
return &indexof($_[0], @acc) >= 0;
}
}
# run_before_apply_command()
# Runs the before-applying command, if any. If it fails, returns the error
# message output
sub run_before_apply_command
{
if ($config{'before_apply_cmd'}) {
local $out = &backquote_logged("($config{'before_apply_cmd'}) &1");
return $out if ($?);
}
return undef;
}
# run_after_apply_command()
# Runs the after-applying command, if any
sub run_after_apply_command
{
if ($config{'after_apply_cmd'}) {
&system_logged("($config{'after_apply_cmd'}) /dev/null 2>&1");
}
}
# run_before_refresh_command()
# Runs the before-refresh command, if any. If it fails, returns the error
# message output
sub run_before_refresh_command
{
if ($config{'before_refresh_cmd'}) {
local $out = &backquote_logged("($config{'before_refresh_cmd'}) &1");
return $out if ($?);
}
return undef;
}
# run_after_refresh_command()
# Runs the after-refresh command, if any
sub run_after_refresh_command
{
if ($config{'after_refresh_cmd'}) {
&system_logged("($config{'after_refresh_cmd'}) /dev/null 2>&1");
}
}
# list_standard_actions()
# Returns a list of standard Shorewall actions
sub list_standard_actions
{
local @rv;
foreach my $a (split(/\t+/, $config{'actions'})) {
open(ACTIONS, "<".$a);
while() {
s/\r|\n//g;
s/#.*$//;
s/\s+$//;
if (/\S/) {
push(@rv, $_);
}
}
close(ACTIONS);
}
if (&version_atleast(3)) {
# Add built-in actions
push(@rv, "allowBcast", "dropBcast", "dropNotSyn", "rejNotSyn",
"dropInvalid", "allowInvalid", "allowoutUPnP", "allowinUPnP",
"forwardUPnP");
}
return &unique(@rv);
}
# list_standard_macros()
# Returns a list of all macro. actions
sub list_standard_macros
{
local @rv;
foreach my $a ($config{'config_dir'}, $config{'macros'}) {
opendir(DIR, $a);
foreach my $f (readdir(DIR)) {
push(@rv, $1) if ($f =~ /^macro\.(.*)$/);
}
closedir(DIR);
}
return &unique(sort(@rv));
}
$BETA_STR = "-Beta";
$BETA_NUM = "\.0000\.";
# get_shorewall_version(nocache)
sub get_shorewall_version
{
local ($nocache) = @_;
local $version;
if (!$nocache && open(VERSION, "<$module_config_directory/version")) {
chop($version = );
close(VERSION);
}
if (!$version) {
local $out = `$config{'shorewall'} version 2>&1`;
$out =~ s/\r//g;
$out =~ s/$BETA_STR/$BETA_NUM/i; # Convert beta string to version number.
if ($out =~ /(\n|^)([0-9\.]+)\n/) {
$version = $2;
}
}
return $version;
}
sub get_printable_version($)
{
local $out = $_[0];
$out =~ s/$BETA_NUM/$BETA_STR/i; # Convert version number back to string.
return $out;
}
sub list_protocols
{
local @stdprotos = ( 'tcp', 'udp', 'icmp' );
local @otherprotos;
open(PROTOS, ") {
s/\r|\n//g;
s/#.*$//;
push(@otherprotos, $1) if (/^(\S+)\s+(\d+)/);
}
close(PROTOS);
@otherprotos = sort { lc($a) cmp lc($b) } @otherprotos;
return &unique(@stdprotos, @otherprotos);
}
# options_input(name, value, &opts)
sub options_input
{
local ($name, $value, $opts) = @_;
local %opts = map { $_, 1 } split(/,/, $value);
print "\n";
}
1;