PageRenderTime 41ms CodeModel.GetById 37ms app.highlight 2ms RepoModel.GetById 0ms app.codeStats 0ms

/sendmail-8.14.5/contrib/cidrexpand

#
Perl | 138 lines | 80 code | 7 blank | 51 comment | 7 complexity | 468fb319bea2596cf1c825b5f186e110 MD5 | raw file
  1#!/usr/bin/perl -w
  2
  3# $Id: cidrexpand,v 8.8 2006/08/07 17:18:37 ca Exp $
  4#
  5# v 0.4
  6#
  7# 17 July 2000 Derek J. Balling (dredd@megacity.org)
  8# 
  9# Acts as a preparser on /etc/mail/access_db to allow you to use address/bit
 10# notation. 
 11#
 12# If you have two overlapping CIDR blocks with conflicting actions
 13# e.g.   10.2.3.128/25 REJECT and 10.2.3.143 ACCEPT
 14# make sure that the exceptions to the more general block are specified
 15# later in the access_db.
 16#
 17# the -r flag to makemap will make it "do the right thing"
 18#
 19# Modifications
 20# -------------
 21# 26 Jul 2001 Derek Balling (dredd@megacity.org)
 22#     Now uses Net::CIDR because it makes life a lot easier.
 23#
 24#  5 Nov 2002 Richard Rognlie (richard@sendmail.com)
 25#     Added code to deal with the prefix tags that may now be included in
 26#     the access_db
 27#
 28#     Added clarification in the notes for what to do if you have 
 29#     exceptions to a larger CIDR block.
 30#
 31#  26 Jul 2006 Richard Rognlie (richard@sendmail.com>
 32#     Added code to strip "comments" (anything after a non-escaped #)
 33#     # characters after a \ or within quotes (single and double) are
 34#     left intact. 
 35#
 36#     e.g.
 37#	From:1.2.3.4	550 Die spammer # spammed us 2006.07.26
 38#     becomes
 39#	From:1.2.3.4	550 Die spammer 
 40#
 41#  3 August 2006
 42#
 43#     Corrected a bug to have it handle the special case of "0.0.0.0/0"
 44#     since Net::CIDR doesn't handle it properly.
 45#
 46# usage: 
 47#  cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
 48#
 49#
 50# Report bugs to: <dredd@megacity.org>
 51#
 52
 53
 54use strict;
 55use Net::CIDR;
 56use Getopt::Std;
 57
 58our ($opt_c,$opt_t);
 59getopts('ct:');
 60
 61my $spaceregex = '\s+';
 62if ($opt_t)
 63{
 64    $spaceregex = $opt_t;
 65}
 66
 67while (<>)
 68{
 69    chomp;
 70    my ($prefix,$left,$right,$space);
 71
 72    if ( (/\#/) && $opt_c )
 73    {
 74	# print "checking...\n";
 75	my $i;
 76	my $qtype='';
 77	for ($i=0 ; $i<length($_) ; $i++) 
 78	{
 79	    my $ch = substr($_,$i,1);
 80	    if ($ch eq '\\') 
 81	    {
 82		$i++;
 83		next;
 84	    }
 85	    elsif ($qtype eq '' && $ch eq '#') 
 86	    {
 87		substr($_,$i) = '';
 88		last;
 89	    }
 90	    elsif ($qtype ne '' && $ch eq $qtype) 
 91	    {
 92		$qtype = '';
 93	    }
 94	    elsif ($qtype eq '' && $ch =~ /[\'\"]/) 
 95	    {
 96		$qtype = $ch;
 97	    }
 98	}
 99    } 
100    
101    if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ )
102    {
103	print "$_\n";
104    }
105    else
106    {
107	($prefix,$left,$space,$right) = 
108	    /^(|\S\S*:)((?:\d+\.){3}\d+\/\d\d?)($spaceregex)(.*)$/;
109	
110	my @new_lefts = expand_network($left);
111	foreach my $nl (@new_lefts)
112	{
113	    print "$prefix$nl$space$right\n";
114	}
115    }
116}
117    
118sub expand_network
119{
120    my $left_input = shift;
121    my @rc = ($left_input);
122    my ($network,$mask) = split /\//, $left_input;
123    if (defined $mask)
124    {
125	return (0..255)	if $mask == 0;
126
127	my @parts = split /\./, $network;
128	while ($#parts < 3)
129	{
130	    push @parts, "0";
131	}
132	my $clean_input = join '.', @parts;
133	$clean_input .= "/$mask";
134	my @octets = Net::CIDR::cidr2octets($clean_input);
135	@rc = @octets;
136    }
137    return @rc;
138}