From a4f8efae408035a6238681c3bac808ff4d2fc32e Mon Sep 17 00:00:00 2001 From: teastep Date: Wed, 14 Mar 2007 03:24:28 +0000 Subject: [PATCH] Add Interfaces module git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5518 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- New/Shorewall/Interfaces.pm | 188 ++++++++++++++++++++++++++++++++++++ New/compiler.pl | 178 +--------------------------------- 2 files changed, 189 insertions(+), 177 deletions(-) create mode 100644 New/Shorewall/Interfaces.pm diff --git a/New/Shorewall/Interfaces.pm b/New/Shorewall/Interfaces.pm new file mode 100644 index 000000000..7e56e444f --- /dev/null +++ b/New/Shorewall/Interfaces.pm @@ -0,0 +1,188 @@ +package Shorewall::Interfaces; +require Exporter; +use Shorewall::Common; +use Shorewall::Config; + +our @ISA = qw(Exporter); +our @EXPORT = qw( validate_interfaces_file dump_interface_info known_interface @interfaces %interfaces ); +our @EXPORT_OK = (); +our @VERSION = 1.00; + +# +# Interface Table. +# +# @interfaces lists the interface names in the order that they appear in the interfaces file. +# +# %interfaces { => { root => +# broadcast => [ , ... ] +# options => { = , +# ... +# } +# zone => +# } +# +my @interfaces; +my %interfaces; + +# +# Parse the interfaces file. +# +sub validate_interfaces_file() +{ + my %validoptions = (arp_filter => 1, + arp_ignore => 1, + blacklist => 1, + detectnets => 1, + dhcp => 1, + maclist => 1, + logmartians => 1, + norfc1918 => 1, + nosmurfs => 1, + proxyarp => 1, + routeback => 1, + routefilter => 1, + sourceroute => 1, + tcpflags => 1, + upnp => 1, + ); + + open INTERFACES, "$ENV{TMP_DIR}/interfaces" or fatal_error "Unable to open stripped interfaces file: $!"; + + while ( $line = ) { + + chomp $line; + $line =~ s/\s+/ /g; + + my ($zone, $interface, $networks, $options, $extra) = split /\s+/, $line; + my $zoneref; + + fatal_error "Invalid interfaces entry: $line" if $extra; + + if ( $zone eq '-' ) { + $zone = ''; + } else { + $zoneref = $zones{$zone}; + + fatal_error "Unknown zone ($zone)" unless $zoneref; + fatal_error "Firewall zone not allowed in ZONE column of interface record" if $zoneref->{type} eq 'firewall'; + } + + $networks = '' if $networks eq '-'; + $options = '' if $networks eq '-'; + + fatal_error "Duplicate Interface ($interface)" if $interfaces{$interface}; + + fatal_error "Invalid Interface Name: $interface" if $interface =~ /:|^\+$/; + + ( $interfaces{$interface}{root} = $interface ) =~ s/\+$// ; + + if ( $networks && $networks ne '-' ) + { + my @broadcast = split ',', $networks; + $interfaces{$interface}{broadcast} = \@broadcast; + } + + if ( $options ) + { + my %options; + + for my $option (split ',', $options ) + { + next if $option eq '-'; + + if ( $validoptions{$option} ) { + $options{$option} = 1; + } elsif ( $option =~ /^arp_filter=([1-3,8])$/ ) { + $options{arp_filter} = $1; + } else { + warning_message("Invalid Interface option ($option) ignored"); + } + } + + $zoneref->{options}{in_out}{routeback} = 1 if $options{routeback}; + + $interfaces{$interface}{options} = \%options; + } + + push @interfaces, $interface; + + add_group_to_zone( $zone, $zoneref->{type}, $interface, \@allipv4, {} ) if $zone; + + $interfaces{$interface}{zone} = $zone; #Must follow the call to add_group_to_zone() + + progress_message " Interface \"$line\" Validated"; + + } + + close INTERFACES; +} + +# +# Dump the tables built by validate_interface_file +# +sub dump_interface_info() +{ + print "\n"; + + for my $interface ( @interfaces ) { + my $interfaceref = $interfaces{$interface}; + print "Interface: $interface\n"; + my $root = $interfaceref->{root}; + print " Root = $root\n"; + my $bcastref = $interfaceref->{broadcast}; + if ( $bcastref ) { + my $spaces = ''; + print ' Broadcast: '; + for my $addr (@$bcastref) { + print "${spaces}${addr}\n"; + $spaces = ' '; + } + } + + my $options = $interfaceref->{options}; + + if ( $options ) { + print ' Options: '; + my $spaces = ''; + for my $option ( keys %$options ) { + my $val = ${$options}{$option}; + print "${spaces}${option} = $val\n"; + $spaces = ' '; + } + } + + my $zone = $interfaceref->{zone}; + print " zone: $zone\n" if $zone; + } + + print "\n"; +} + +# +# Returns true if passed interface matches an entry in /etc/shorewall/interfaces +# +# If the passed name matches a wildcard, a entry for the name is added in %interfaces to speed up validation of other references to that name. +# +sub known_interface($) +{ + my $interface = $_[0]; + + return 1 if exists $interfaces{$interface}; + + for my $i ( @interfaces ) { + my $val = $interfaces{$i}{root}; + next if $val eq $i; + my $len = length $val; + if ( substr( $interface, 0, $len ) eq $val ) { + # + # Cache this result for future reference + # + $interfaces{$interface} = undef; + return 1; + } + } + + 0; +} + +1; diff --git a/New/compiler.pl b/New/compiler.pl index e9c0d9bcc..439464392 100755 --- a/New/compiler.pl +++ b/New/compiler.pl @@ -8,6 +8,7 @@ use Shorewall::Common; use Shorewall::Config; use Shorewall::Chains; use Shorewall::Zones; +use Shorewall::Interfaces; # # IPSEC Option types @@ -23,22 +24,6 @@ my ( $command, $doing, $done ) = qw/ compile Compiling Compiled/; #describe the my $tempfile = ''; # Temporary object file name -# -# Interface Table. -# -# @interfaces lists the interface names in the order that they appear in the interfaces file. -# -# %interfaces { => { root => -# broadcast => [ , ... ] -# options => { = , -# ... -# } -# zone => -# } -# -my @interfaces; -my %interfaces; - # # Contents of last COMMENT line. # @@ -148,167 +133,6 @@ my %default_actions = ( DROP => 'none' , ACCEPT => 'none' , QUEUE => 'none' ); -# -# Parse the interfaces file. -# -sub validate_interfaces_file() -{ - my %validoptions = (arp_filter => 1, - arp_ignore => 1, - blacklist => 1, - detectnets => 1, - dhcp => 1, - maclist => 1, - logmartians => 1, - norfc1918 => 1, - nosmurfs => 1, - proxyarp => 1, - routeback => 1, - routefilter => 1, - sourceroute => 1, - tcpflags => 1, - upnp => 1, - ); - - open INTERFACES, "$ENV{TMP_DIR}/interfaces" or fatal_error "Unable to open stripped interfaces file: $!"; - - while ( $line = ) { - - chomp $line; - $line =~ s/\s+/ /g; - - my ($zone, $interface, $networks, $options, $extra) = split /\s+/, $line; - my $zoneref; - - fatal_error "Invalid interfaces entry: $line" if $extra; - - if ( $zone eq '-' ) { - $zone = ''; - } else { - $zoneref = $zones{$zone}; - - fatal_error "Unknown zone ($zone)" unless $zoneref; - fatal_error "Firewall zone not allowed in ZONE column of interface record" if $zoneref->{type} eq 'firewall'; - } - - $networks = '' if $networks eq '-'; - $options = '' if $networks eq '-'; - - fatal_error "Duplicate Interface ($interface)" if $interfaces{$interface}; - - fatal_error "Invalid Interface Name: $interface" if $interface =~ /:|^\+$/; - - ( $interfaces{$interface}{root} = $interface ) =~ s/\+$// ; - - if ( $networks && $networks ne '-' ) - { - my @broadcast = split ',', $networks; - $interfaces{$interface}{broadcast} = \@broadcast; - } - - if ( $options ) - { - my %options; - - for my $option (split ',', $options ) - { - next if $option eq '-'; - - if ( $validoptions{$option} ) { - $options{$option} = 1; - } elsif ( $option =~ /^arp_filter=([1-3,8])$/ ) { - $options{arp_filter} = $1; - } else { - warning_message("Invalid Interface option ($option) ignored"); - } - } - - $zoneref->{options}{in_out}{routeback} = 1 if $options{routeback}; - - $interfaces{$interface}{options} = \%options; - } - - push @interfaces, $interface; - - add_group_to_zone( $zone, $zoneref->{type}, $interface, \@allipv4, {} ) if $zone; - - $interfaces{$interface}{zone} = $zone; #Must follow the call to add_group_to_zone() - - progress_message " Interface \"$line\" Validated"; - - } - - close INTERFACES; -} - -# -# Dump the tables built by validate_interface_file -# -sub dump_interface_info() -{ - print "\n"; - - for my $interface ( @interfaces ) { - my $interfaceref = $interfaces{$interface}; - print "Interface: $interface\n"; - my $root = $interfaceref->{root}; - print " Root = $root\n"; - my $bcastref = $interfaceref->{broadcast}; - if ( $bcastref ) { - my $spaces = ''; - print ' Broadcast: '; - for my $addr (@$bcastref) { - print "${spaces}${addr}\n"; - $spaces = ' '; - } - } - - my $options = $interfaceref->{options}; - - if ( $options ) { - print ' Options: '; - my $spaces = ''; - for my $option ( keys %$options ) { - my $val = ${$options}{$option}; - print "${spaces}${option} = $val\n"; - $spaces = ' '; - } - } - - my $zone = $interfaceref->{zone}; - print " zone: $zone\n" if $zone; - } - - print "\n"; -} - -# -# Returns true if passed interface matches an entry in /etc/shorewall/interfaces -# -# If the passed name matches a wildcard, a entry for the name is added in %interfaces to speed up validation of other references to that name. -# -sub known_interface($) -{ - my $interface = $_[0]; - - return 1 if exists $interfaces{$interface}; - - for my $i ( @interfaces ) { - my $val = $interfaces{$i}{root}; - next if $val eq $i; - my $len = length $val; - if ( substr( $interface, 0, $len ) eq $val ) { - # - # Cache this result for future reference - # - $interfaces{$interface} = undef; - return 1; - } - } - - 0; -} - # # Validates the hosts file. Generates entries in %zone{..}{hosts} #