Home | History | Annotate | Line # | Download | only in perl
      1  1.1  christos #!/usr/bin/perl -w
      2  1.1  christos #
      3  1.1  christos # Written by Camiel Dobbelaar <cd (at] sentia.nl>, Aug-2000
      4  1.1  christos # ipfmeta is in the Public Domain.
      5  1.1  christos #
      6  1.1  christos 
      7  1.1  christos use strict;
      8  1.1  christos use Getopt::Std;
      9  1.1  christos 
     10  1.1  christos ## PROCESS COMMANDLINE
     11  1.1  christos our($opt_v); $opt_v=1;
     12  1.1  christos getopts('v:') || die "usage: ipfmeta [-v verboselevel] [objfile]\n";
     13  1.1  christos my $verbose = $opt_v + 0;
     14  1.1  christos my $objfile = shift || "ipf.objs";
     15  1.1  christos my $MAXRECURSION = 10;
     16  1.1  christos 
     17  1.1  christos ## READ OBJECTS
     18  1.1  christos open(FH, "$objfile") || die "cannot open $objfile: $!\n";
     19  1.1  christos my @tokens;
     20  1.1  christos while (<FH>) {
     21  1.1  christos 	chomp;
     22  1.1  christos 	s/#.*$//;	# remove comments
     23  1.1  christos 	s/^\s+//;	# compress whitespace
     24  1.1  christos 	s/\s+$//;
     25  1.1  christos 	next if m/^$/;	# skip empty lines
     26  1.1  christos 	push (@tokens, split);
     27  1.1  christos }
     28  1.1  christos close(FH) || die "cannot close $objfile: $!\n";
     29  1.1  christos # link objects with their values
     30  1.1  christos my $obj="";
     31  1.1  christos my %objs;
     32  1.1  christos while (@tokens) {
     33  1.1  christos 	my $token = shift(@tokens);
     34  1.1  christos 	if ($token =~ m/^\[([^]]*)\]$/) {
     35  1.1  christos 		# new object
     36  1.1  christos 		$obj = $1;
     37  1.1  christos 	} else {
     38  1.1  christos 		# new value
     39  1.1  christos 		push(@{$objs{$obj}}, $token) unless ($obj eq "");
     40  1.1  christos 	}
     41  1.1  christos }
     42  1.1  christos 
     43  1.1  christos # sort objects: longest first
     44  1.1  christos my @objs = sort { length($b) <=> length($a) } keys %objs;
     45  1.1  christos 
     46  1.1  christos ## SUBSTITUTE OBJECTS WITH THEIR VALUES FROM STDIN
     47  1.1  christos foreach (<STDIN>) {
     48  1.1  christos 	foreach (expand($_, 0)) {
     49  1.1  christos 		print;
     50  1.1  christos 	}
     51  1.1  christos }
     52  1.1  christos 
     53  1.1  christos ## END
     54  1.1  christos 
     55  1.1  christos sub expand {
     56  1.1  christos 	my $line = shift;
     57  1.1  christos 	my $level = shift;
     58  1.1  christos 	my @retlines = $line;
     59  1.1  christos 	my $obj;
     60  1.1  christos 	my $val;
     61  1.1  christos 
     62  1.1  christos 	# coarse protection
     63  1.1  christos 	if ($level > $MAXRECURSION) {
     64  1.1  christos 		print STDERR "ERR: recursion exceeds $MAXRECURSION levels\n";
     65  1.1  christos 		return;
     66  1.1  christos 	}
     67  1.1  christos 
     68  1.1  christos 	foreach $obj (@objs) {
     69  1.1  christos 		if ($line =~ m/$obj/) {
     70  1.1  christos 			@retlines = "";
     71  1.1  christos 			if ($level < $verbose) {
     72  1.1  christos 				# add metarule as a comment
     73  1.1  christos 				push(@retlines, "# ".$line);
     74  1.1  christos 			}
     75  1.1  christos 			foreach $val (@{$objs{$obj}}) {
     76  1.1  christos 				my $newline = $line;
     77  1.1  christos 				$newline =~ s/$obj/$val/;
     78  1.1  christos 				push(@retlines, expand($newline, $level+1));
     79  1.1  christos 			}
     80  1.1  christos 			last;
     81  1.1  christos 		}
     82  1.1  christos 	}
     83  1.1  christos 
     84  1.1  christos 	return @retlines;
     85  1.1  christos }
     86  1.1  christos 
     87  1.1  christos __END__
     88  1.1  christos 
     89  1.1  christos =head1 NAME
     90  1.1  christos 
     91  1.1  christos B<ipfmeta> - use objects in IP filter files
     92  1.1  christos 
     93  1.1  christos =head1 SYNOPSIS
     94  1.1  christos 
     95  1.1  christos B<ipfmeta> [F<options>] [F<objfile>]
     96  1.1  christos 
     97  1.1  christos =head1 DESCRIPTION
     98  1.1  christos 
     99  1.1  christos B<ipfmeta> is used to simplify the maintenance of your IP filter
    100  1.1  christos ruleset. It does this through the use of 'objects'.  A matching
    101  1.1  christos object gets replaced by its values at runtime.  This is similar to
    102  1.1  christos what a macro processor like m4 does.
    103  1.1  christos 
    104  1.1  christos B<ipfmeta> is specifically geared towards IP filter. It is line
    105  1.1  christos oriented, if an object has multiple values, the line with the object
    106  1.1  christos is duplicated and substituted for each value. It is also recursive,
    107  1.1  christos an object may have another object as a value.
    108  1.1  christos 
    109  1.1  christos Rules to be processed are read from stdin, output goes to stdout.
    110  1.1  christos 
    111  1.1  christos The verbose option allows for the inclusion of the metarules in the
    112  1.1  christos output as comments.
    113  1.1  christos 
    114  1.1  christos Definition of the objects and their values is done in a separate
    115  1.1  christos file, the filename defaults to F<ipf.objs>.  An object is delimited
    116  1.1  christos by square brackets. A value is delimited by whitespace.  Comments
    117  1.1  christos start with '#' and end with a newline. Empty lines and extraneous
    118  1.1  christos whitespace are allowed.  A value belongs to the first object that
    119  1.1  christos precedes it.
    120  1.1  christos 
    121  1.1  christos It is recommended that you use all caps or another distinguishing
    122  1.1  christos feature for object names. You can use B<ipfmeta> for NAT rules also,
    123  1.1  christos for instance to keep them in sync with filter rules.  Combine
    124  1.1  christos B<ipfmeta> with a Makefile to save typing.
    125  1.1  christos 
    126  1.1  christos =head1 OPTIONS
    127  1.1  christos 
    128  1.1  christos =over 4
    129  1.1  christos 
    130  1.1  christos =item B<-v> I<verboselevel>
    131  1.1  christos 
    132  1.1  christos Include metarules in output as comments. Default is 1, the top level
    133  1.1  christos metarules. Higher levels cause expanded metarules to be included.
    134  1.1  christos Level 0 does not add comments at all.
    135  1.1  christos 
    136  1.1  christos =back
    137  1.1  christos 
    138  1.1  christos =head1 BUGS
    139  1.1  christos 
    140  1.1  christos A value can not have whitespace in it.
    141  1.1  christos 
    142  1.1  christos =head1 EXAMPLE
    143  1.1  christos 
    144  1.1  christos (this does not look good, formatted)
    145  1.1  christos 
    146  1.1  christos I<ipf.objs>
    147  1.1  christos 
    148  1.1  christos [PRIVATE] 10.0.0.0/8 127.0.0.0/8 172.16.0.0/12 192.168.0.0/16
    149  1.1  christos 
    150  1.1  christos [MULTICAST] 224.0.0.0/4
    151  1.1  christos 
    152  1.1  christos [UNWANTED] PRIVATE MULTICAST
    153  1.1  christos 
    154  1.1  christos [NOC] xxx.yy.zz.1/32 xxx.yy.zz.2/32
    155  1.1  christos 
    156  1.1  christos [WEBSERVERS] 192.168.1.1/32 192.168.1.2/32
    157  1.1  christos 
    158  1.1  christos [MGMT-PORTS] 22 23
    159  1.1  christos 
    160  1.1  christos I<ipf.metarules>
    161  1.1  christos 
    162  1.1  christos block in from UNWANTED to any
    163  1.1  christos 
    164  1.1  christos pass  in from NOC to WEBSERVERS port = MGMT-PORTS
    165  1.1  christos 
    166  1.1  christos pass  out all
    167  1.1  christos 
    168  1.1  christos I<Run>
    169  1.1  christos 
    170  1.1  christos ipfmeta ipf.objs <ipf.metarules >ipf.rules
    171  1.1  christos 
    172  1.1  christos I<Output>
    173  1.1  christos 
    174  1.1  christos # block in from UNWANTED to any
    175  1.1  christos 
    176  1.1  christos block in from 10.0.0.0/8 to any
    177  1.1  christos 
    178  1.1  christos block in from 127.0.0.0/8 to any
    179  1.1  christos 
    180  1.1  christos block in from 172.16.0.0/12 to any
    181  1.1  christos 
    182  1.1  christos block in from 192.168.0.0/16 to any
    183  1.1  christos 
    184  1.1  christos block in from 224.0.0.0/4 to any
    185  1.1  christos 
    186  1.1  christos # pass  in from NOC to WEBSERVERS port = MGMT-PORTS
    187  1.1  christos 
    188  1.1  christos pass  in from xxx.yy.zz.1/32 to 192.168.1.1/32 port = 22
    189  1.1  christos 
    190  1.1  christos pass  in from xxx.yy.zz.1/32 to 192.168.1.1/32 port = 23
    191  1.1  christos 
    192  1.1  christos pass  in from xxx.yy.zz.1/32 to 192.168.1.2/32 port = 22
    193  1.1  christos 
    194  1.1  christos pass  in from xxx.yy.zz.1/32 to 192.168.1.2/32 port = 23
    195  1.1  christos 
    196  1.1  christos pass  in from xxx.yy.zz.2/32 to 192.168.1.1/32 port = 22
    197  1.1  christos 
    198  1.1  christos pass  in from xxx.yy.zz.2/32 to 192.168.1.1/32 port = 23
    199  1.1  christos 
    200  1.1  christos pass  in from xxx.yy.zz.2/32 to 192.168.1.2/32 port = 22
    201  1.1  christos 
    202  1.1  christos pass  in from xxx.yy.zz.2/32 to 192.168.1.2/32 port = 23
    203  1.1  christos 
    204  1.1  christos pass  out all
    205  1.1  christos 
    206  1.1  christos =head1 AUTHOR
    207  1.1  christos 
    208  1.1  christos Camiel Dobbelaar <cd@sentia.nl>. B<ipfmeta> is in the Public Domain.
    209  1.1  christos 
    210  1.1  christos =cut
    211