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