source: trunk/third/sendmail/contrib/cidrexpand @ 19204

Revision 19204, 3.2 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
  • Property svn:executable set to *
Line 
1#!/usr/local/bin/perl -w
2
3# v 0.2-very-beta
4#
5# 17 July 2000 Derek J. Balling (dredd@megacity.org)
6#
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...
11#
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.
15#
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.
20#
21# the -r flag to makemap will make it "do the right thing"
22#
23# Modifications
24# -------------
25#  5 Nov  2002 Richard Rognlie (richard@sendmail.com)
26#     Added code to deal with the prefix tags that may now be included in
27#     the access_db
28#
29#     Added clarification in the notes for what to do if you have
30#     exceptions to a larger CIDR block.
31#
32# usage:
33#  cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
34#
35# Report bugs to: dredd@megacity.org
36#
37
38my $spaceregex = '\s+';
39
40while (my $arg = shift @ARGV)
41{
42     if ($arg eq '-t')
43     {
44        $spaceregex = shift;
45     }
46}
47
48use strict;
49
50my $SENDMAIL = 1;
51
52while (<>)
53{
54     my ($prefix,$left,$right,$space);
55
56     if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ )
57     {
58        print;
59     }
60     else
61     {
62        ($prefix,$left,$space,$right) = /^(|\S\S*:)((?:\d+\.){3}\d+\/\d\d?)($spaceregex)(.*)$/;
63
64        my @new_lefts = expand_network($left);
65        foreach my $nl (@new_lefts)
66        {
67            print "$prefix$nl$space$right\n";
68        }
69
70     }
71}
72   
73sub expand_network
74{
75     my ($network,$mask) = split /\//, shift;
76     my @diffs = calc_changes($network,$mask);
77     my ($first,$second,$third,$fourth) = split /\./, $network;
78
79     my @rc = ();
80
81     for my $f ($first..($first+$diffs[0]))
82     {
83        if ( ( $SENDMAIL ) and ($diffs[1] == 255))
84        {
85            push @rc, "$f";
86        }
87        else
88        {
89            for my $s ($second..($second+$diffs[1]))
90            {
91                if ( ($SENDMAIL) and ($diffs[2] == 255) )
92                {
93                    push @rc,"$f\.$s";
94                }
95                else
96                {
97                    for my $t ($third..($third+$diffs[2]))
98                    {
99                        if ( ($SENDMAIL) and ($diffs[3] == 255))
100                        {
101                            push @rc, "$f\.$s\.$t";
102                        }
103                        else
104                        {
105                            for my $fr ($fourth..($fourth+$diffs[3]))
106                            {
107                                push @rc, "$f\.$s\.$t\.$fr";
108                            }
109                        }
110                    }
111                }
112            }
113        }
114     }
115     return @rc;
116}
117
118sub calc_changes
119{
120     my ($network,$mask) = @_;
121   
122     my @octs = split /\./, $network;
123   
124     my ($first,$second,$third,$fourth) = (0,0,0,0);
125   
126     my $power = 32 - $mask;
127   
128     if ($mask > 24)
129     {
130        $fourth = 2**$power - 1;
131     }
132     elsif ($mask > 16)
133     {
134        $fourth = 255;
135        $third = 2**($power-8) - 1;
136     }
137     elsif ($mask > 8)
138     {
139        $fourth = 255;
140        $third  = 255;
141        $second = 2**($power-16) - 1;
142     }
143     elsif ($mask > 0)
144     {
145        $fourth = 255;
146        $third = 255;
147        $second = 255;
148        $first = 2**($power-24) - 1;
149     }
150     elsif ($mask == 0)
151     {
152        $fourth = 255;
153        $third = 255;
154        $second = 255;
155        $first = 255;
156     }
157
158     return ($first,$second,$third,$fourth);
159}
Note: See TracBrowser for help on using the repository browser.