3 # Written by Camiel Dobbelaar <cd@sentia.nl>, Aug-2000
4 # ipfmeta is in the Public Domain.
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;
18 open(FH
, "$objfile") || die "cannot open $objfile: $!\n";
22 s/#.*$//; # remove comments
23 s/^\s+//; # compress whitespace
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
33 my $token = shift(@tokens);
34 if ($token =~ m/^\[([^]]*)\]$/) {
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
48 foreach (expand
($_, 0)) {
63 if ($level > $MAXRECURSION) {
64 print STDERR
"ERR: recursion exceeds $MAXRECURSION levels\n";
68 foreach $obj (@objs) {
69 if ($line =~ m/$obj/) {
71 if ($level < $verbose) {
72 # add metarule as a comment
73 push(@retlines, "# ".$line);
75 foreach $val (@
{$objs{$obj}}) {
77 $newline =~ s/$obj/$val/;
78 push(@retlines, expand
($newline, $level+1));
91 B<ipfmeta> - use objects in IP filter files
95 B<ipfmeta> [F<options>] [F<objfile>]
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
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
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.
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.
140 A value can not have whitespace in it.
144 (this does not look good, formatted)
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
162 block in from UNWANTED to any
164 pass in from NOC to WEBSERVERS port = MGMT-PORTS
170 ipfmeta ipf.objs <ipf.metarules >ipf.rules
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
208 Camiel Dobbelaar <cd@sentia.nl>. B<ipfmeta> is in the Public Domain.