cidrexpand revision 266692
1178580Simp#!/usr/bin/perl -w 2178580Simp 3178580Simp# $Id: cidrexpand,v 8.8 2006-08-07 17:18:37 ca Exp $ 4178580Simp# 5178580Simp# v 0.4 6178580Simp# 7178580Simp# 17 July 2000 Derek J. Balling (dredd@megacity.org) 8178580Simp# 9178580Simp# Acts as a preparser on /etc/mail/access_db to allow you to use address/bit 10178580Simp# notation. 11178580Simp# 12178580Simp# If you have two overlapping CIDR blocks with conflicting actions 13178580Simp# e.g. 10.2.3.128/25 REJECT and 10.2.3.143 ACCEPT 14178580Simp# make sure that the exceptions to the more general block are specified 15178580Simp# later in the access_db. 16178580Simp# 17178580Simp# the -r flag to makemap will make it "do the right thing" 18178580Simp# 19178580Simp# Modifications 20178580Simp# ------------- 21178580Simp# 26 Jul 2001 Derek Balling (dredd@megacity.org) 22178580Simp# Now uses Net::CIDR because it makes life a lot easier. 23178580Simp# 24178580Simp# 5 Nov 2002 Richard Rognlie (richard@sendmail.com) 25178580Simp# Added code to deal with the prefix tags that may now be included in 26178580Simp# the access_db 27178580Simp# 28178580Simp# Added clarification in the notes for what to do if you have 29178580Simp# exceptions to a larger CIDR block. 30178580Simp# 31178580Simp# 26 Jul 2006 Richard Rognlie (richard@sendmail.com> 32178580Simp# Added code to strip "comments" (anything after a non-escaped #) 33178580Simp# # characters after a \ or within quotes (single and double) are 34178580Simp# left intact. 35178580Simp# 36178580Simp# e.g. 37178580Simp# From:1.2.3.4 550 Die spammer # spammed us 2006.07.26 38178580Simp# becomes 39178580Simp# From:1.2.3.4 550 Die spammer 40178580Simp# 41178580Simp# 3 August 2006 42178580Simp# 43178580Simp# Corrected a bug to have it handle the special case of "0.0.0.0/0" 44178580Simp# since Net::CIDR doesn't handle it properly. 45178580Simp# 46178580Simp# usage: 47178580Simp# cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access 48178580Simp# 49178580Simp# 50178580Simp# Report bugs to: <dredd@megacity.org> 51178580Simp# 52178580Simp 53178580Simp 54178580Simpuse strict; 55178580Simpuse Net::CIDR; 56178580Simpuse 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} 139