1 #!/usr/local/bin/perl -w
5 # 17 July 2000 Derek J. Balling (dredd@megacity.org)
7 # The $SENDMAIL flag tells the code to lump networks in sendmail format
8 # if applicable. If this flag is disabled, cidrexpand will literally create
9 # a single line for each entry, which may or may not be what you want. :)
10 # makes for a rather large hash table...
12 # Acts as a preparser on /etc/mail/access_db to allow you to use address/bit
13 # notation. Caveat: the address portion MUST be the start address or your
14 # results will NOT be what what you want.
16 # If you have two overlapping CIDR blocks with conflicting actions
17 # e.g. 10.2.3.128/25 REJECT and 10.2.3.143 ACCEPT
18 # make sure that the exceptions to the more general block are specified
19 # later in the access_db.
21 # the -r flag to makemap will make it "do the right thing"
25 # 5 Nov 2002 Richard Rognlie (richard@sendmail.com)
26 # Added code to deal with the prefix tags that may now be included in
29 # Added clarification in the notes for what to do if you have
30 # exceptions to a larger CIDR block.
33 # cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
35 # Report bugs to: dredd@megacity.org
38 my $spaceregex = '\s+';
40 while (my $arg = shift @ARGV)
54 my ($prefix,$left,$right,$space);
56 if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ )
62 ($prefix,$left,$space,$right) = /^(|\S\S*:)((?:\d+\.){3}\d+\/\d\d?)($spaceregex)(.*)$/;
64 my @new_lefts = expand_network($left);
65 foreach my $nl (@new_lefts)
67 print "$prefix$nl$space$right\n";
75 my ($network,$mask) = split /\//, shift;
76 my @diffs = calc_changes($network,$mask);
77 my ($first,$second,$third,$fourth) = split /\./, $network;
81 for my $f ($first..($first+$diffs[0]))
83 if ( ( $SENDMAIL ) and ($diffs[1] == 255))
89 for my $s ($second..($second+$diffs[1]))
91 if ( ($SENDMAIL) and ($diffs[2] == 255) )
97 for my $t ($third..($third+$diffs[2]))
99 if ( ($SENDMAIL) and ($diffs[3] == 255))
101 push @rc, "$f\.$s\.$t";
105 for my $fr ($fourth..($fourth+$diffs[3]))
107 push @rc, "$f\.$s\.$t\.$fr";
120 my ($network,$mask) = @_;
122 my @octs = split /\./, $network;
124 my ($first,$second,$third,$fourth) = (0,0,0,0);
126 my $power = 32 - $mask;
130 $fourth = 2**$power - 1;
135 $third = 2**($power-8) - 1;
141 $second = 2**($power-16) - 1;
148 $first = 2**($power-24) - 1;
158 return ($first,$second,$third,$fourth);