# # Shorewall-perl 4.0 -- /usr/share/shorewall-perl/Shorewall/Macros.pm # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # (c) 2007 - Tom Eastep (teastep@shorewall.net) # # Complete documentation is available at http://shorewall.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA # # This module exports some low-level module-oriented functions. # package Shorewall::Macros; require Exporter; use Shorewall::Common; use Shorewall::Config; use Shorewall::Zones; use Shorewall::Chains; use strict; our @ISA = qw(Exporter); our @EXPORT = qw( find_macro split_action substitute_param merge_macro_source_dest merge_macro_column %macros ); our @EXPORT_OK = qw( initialize ); our @VERSION = 1.00; our %macros; # # Initialize globals -- we take this novel approach to globals initialization to allow # the compiler to run multiple times in the same process. The # initialize() function does globals initialization for this # module and is called from an INIT block below. The function is # also called by Shorewall::Compiler::compiler at the beginning of # the second and subsequent calls to that function. # sub initialize() { %macros = (); } INIT { initialize; } # # Try to find a macro file -- RETURNS false if the file doesn't exist or MACRO if it does. # If the file exists, the macro is entered into the 'targets' table and the fully-qualified # name of the file is stored in the 'macro' table. # sub find_macro( $ ) { my $macro = $_[0]; my $macrofile = find_file "macro.$macro"; if ( -f $macrofile ) { $macros{$macro} = $macrofile; $targets{$macro} = MACRO; } else { 0; } } # # Return ( action, level[:tag] ) from passed full action # sub split_action ( $ ) { my $action = $_[0]; my @a = split( /:/ , $action, 4 ); fatal_error "Invalid ACTION ($action)" if ( $action =~ /::/ ) || ( @a > 3 ); ( shift @a, join ":", @a ); } # # This function substitutes the second argument for the first part of the first argument up to the first colon (":") # # Example: # # substitute_param DNAT PARAM:info:FTP # # produces "DNAT:info:FTP" # sub substitute_param( $$ ) { my ( $param, $action ) = @_; if ( $action =~ /:/ ) { my $logpart = (split_action $action)[1]; $logpart =~ s!/$!!; return "$param:$logpart"; } $param; } # # Combine fields from a macro body with one from the macro invocation # sub merge_macro_source_dest( $$ ) { my ( $body, $invocation ) = @_; if ( $invocation ) { if ( $body ) { return $body if $invocation eq '-'; return "$body:$invocation" if $invocation =~ /.*?\.*?\.|^\+|^~|^!~/; return "$invocation:$body"; } return $invocation; } $body || ''; } sub merge_macro_column( $$ ) { my ( $body, $invocation ) = @_; if ( defined $invocation && $invocation ne '' && $invocation ne '-' ) { $invocation; } else { $body; } } 1;