Detect stuff now working\!

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5650 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2007-03-23 22:47:21 +00:00
parent 04943614e4
commit 6abf8f224d
2 changed files with 94 additions and 44 deletions

View File

@ -950,6 +950,31 @@ sub log_rule( $$$$ ) {
log_rule_limit $level, $chainref, $chainref->{name} , $disposition, $env{LOGLIMIT}, '', 'add', $predicates;
}
#
# Keep track of which interfaces have active 'address' variables
#
my %interfaceaddrs;
#
# Returns the name of the shell variable holding the first address of the passed interface
#
sub interface_address( $ ) {
chain_base( $_[0] ) . '_address';
}
#
# If this is the first time that the first address of an interface has been requested, emit a run-time command
# that establishes the value of the associated address variable.
#
sub get_interface_address ( $$ ) {
my ($chainref, $interface ) = @_;
unless ( $interfaceaddrs{$interface } ) {
add_command $chainref, interface_address( $interface ) . "=\$(find_first_interface_address $interface)";
$interfaceaddrs{$interface} = 1;
}
}
#
# This function provides a uniform way to generate rules (something the original Shorewall sorely needed).
#
@ -996,10 +1021,16 @@ sub expand_rule( $$$$$$$$$$ )
fatal_error "Unknown Interface ($iiface): \"$line\"" unless known_interface $iiface;
if ( $restriction == POSTROUTE_RESTRICT ) {
#
# An interface in the SOURCE column of a masq file
#
add_command( $chainref , "sources=\$(get_routed_networks $iiface)" );
add_command( $chainref , qq([ -z "\$sources" ] && fatal_error "Unable to determine the routes through interface \"$iiface\"") );
add_command( $chainref , 'for source in $sources; do' );
$rule .= '-s $source';
$rule .= '-s $source ';
#
# While $loopcount > 0, calls to 'add_rule()' will be converted to calls to 'add_command()'
#
$loopcount++;
} else {
$rule .= "-i $iiface ";
@ -1022,15 +1053,17 @@ sub expand_rule( $$$$$$$$$$ )
add_command $chainref, 'addresses=';
for my $interface ( @interfaces ) {
add_command $chainref , 'addresses="$addresses $(find_first_interface_address $interface)';
add_command $chainref , 'for address in $addresses; do';
get_interface_address $chainref, $interface;
add_command $chainref , 'addresses="$addresses $' . interface_address( $interface ) . '"' ;
}
add_command $chainref , 'for address in $addresses; do';
$rule .= '-d $address ';
$loopcount++;
} else {
add_command $chainref , 'address= $(find_first_interface_address $interface)';
get_interface_address $chainref, $interfaces[0];
$rule .= '-d $' . interface_address( $interfaces[0] ) . ' ';
}
$rule .= '-d $address';
$dest = '';
} elsif ( $dest =~ /^([^:]+):([^:]+)$/ ) {
$diface = $1;
@ -1043,6 +1076,7 @@ sub expand_rule( $$$$$$$$$$ )
} else {
$dest = '';
}
#
# Verify Destination Interface, if any
#
@ -1050,6 +1084,9 @@ sub expand_rule( $$$$$$$$$$ )
fatal_error "Unknown Interface ($diface) in rule \"$line\"" unless known_interface $diface;
if ( $restriction == PREROUTE_RESTRICT ) {
#
# ADDRESS 'detect' in the masq file.
#
add_command $chainref , "dests=\$(find_interface_addresses $diface)";
add_command $chainref , qq([ -z "\$dests" ] && fatal_error "Unable to determine the address(es) of interface \"$diface\"");
add_command $chainref , 'for dest in $dests; do';
@ -1064,35 +1101,46 @@ sub expand_rule( $$$$$$$$$$ )
if ( $origdest eq '-' ) {
$origdest = '';
} elsif ( $origdest =~ /^detect:(.*)$/ ) {
#
# Either the filter part of a DNAT rule or 'detect' was given in the ORIG DEST column
#
my @interfaces = split /\s+/, $1;
if ( @interfaces > 1 ) {
add_command $chainref, 'addresses=';
for my $interface ( @interfaces ) {
add_command $chainref , 'addresses="$addresses $(find_first_interface_address $interface)"';
add_command( $chainref , 'for address in $addresses; do' );
get_interface_address $chainref, $interface;
add_command $chainref , qq(addresses="\$addresses \$(find_first_interface_address $interface)");
}
add_command( $chainref , 'for address in $addresses; do' );
$rule .= '-m conntrack --ctorigdst $address ';
$loopcount++;
} else {
add_command $chainref , 'address="$(find_first_interface_address $interface)"';
get_interface_address $chainref, $interfaces[0];
$rule .= '-m conntrack --ctorigdst $' . interface_address ( $interfaces[0] ) . ' ';
}
$rule .= '-m conntrack --ctorigdst $address';
$origdest = '';
} elsif ( $origdest =~ /^([^!]+)?!([^!]+)$/ ) {
$onets = $1;
$oexcl = $2;
} else {
$oexcl = '';
}
if ( ! $onets ) {
my @oexcl = split /,/, $oexcl;
if ( @oexcl == 1 ) {
$rule .= "-m conntrack --ctorigdst ! $oexcl ";
if ( $origdest =~ /^([^!]+)?!([^!]+)$/ ) {
#
# Exclusion
#
$onets = $1;
$oexcl = $2;
} else {
$oexcl = '';
}
if ( ! $onets ) {
my @oexcl = split /,/, $oexcl;
if ( @oexcl == 1 ) {
$rule .= "-m conntrack --ctorigdst ! $oexcl ";
$oexcl = '';
}
}
}
} else {
$oexcl = '';

View File

@ -913,30 +913,32 @@ sub process_rule1 ( $$$$$$$$$ ) {
#
my $target = '';
if ( $action eq 'SAME' ) {
fatal_error 'Port mapping not allowed in SAME rules' if $serverport;
$target = '-j SAME ';
for my $serv ( split /,/, $server ) {
$target .= "--to $serv ";
}
$serverport = $ports;
} elsif ( $action eq ' -j DNAT' ) {
$serverport = ":$serverport" if $serverport;
for my $serv ( split /,/, $server ) {
$target .= "--to ${serv}${serverport} ";
}
} else {
if ( $actiontype & REDIRECT ) {
$target = '-j REDIRECT --to-port ' . ( $serverport ? $serverport : $ports );
}
} else {
if ( $action eq 'SAME' ) {
fatal_error 'Port mapping not allowed in SAME rules' if $serverport;
$target = '-j SAME ';
for my $serv ( split /,/, $server ) {
$target .= "--to $serv ";
}
unless ( $origdest && $origdest ne '-' && $origdest ne 'detect' ) {
if ( $config{DETECT_DNAT_ADDRS} ) {
my $interfacesref = $zones{$sourcezone}{interfaces};
my $interfaces = "@$interfacesref";
$origdest = $interfaces ? "detect:$interfaces" : ALLIPv4;
} else {
$origdest = ALLIPv4;
$serverport = $ports;
} elsif ( $action eq ' -j DNAT' ) {
$serverport = ":$serverport" if $serverport;
for my $serv ( split /,/, $server ) {
$target .= "--to ${serv}${serverport} ";
}
}
unless ( $origdest && $origdest ne '-' && $origdest ne 'detect' ) {
if ( $config{DETECT_DNAT_IPADDRS} ) {
my $interfacesref = $zones{$sourcezone}{interfaces};
my @interfaces = keys %$interfacesref;
$origdest = @interfaces ? "detect:@interfaces" : ALLIPv4;
} else {
$origdest = ALLIPv4;
}
}
}
#