1 # Network/range syntax and semantics handling.
3 # Copyright (C) 1999 Ian Jackson <ijackson@chiark.greenend.org.uk>
5 # This is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation; either version 2,
8 # or (at your option) any later version.
10 # This is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public
16 # License along with this file; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 sub parse_netrange ($) {
21 my ($prefix,$network,@b,$b,$val,$mask);
23 length $net or finish_error('nonet');
24 print DEBUG "got $net\n";
25 $net =~ s,/(\d+)$,, or finish_error("badnet");
26 print DEBUG "prefix $1\n";
27 $prefix= $1+0; ($prefix >= 0 && $prefix <= 32) or finish_error("badnet");
28 print DEBUG "prefix $1 $net\n";
29 $network= ''; @b= split(/\./,$net);
30 @b<=4 or finish_error("badnet");
31 print DEBUG "big enough\n";
32 @b*8 >= $prefix or finish_error("badnet");
33 while (@b<4) { push @b,0; }
36 $b>=0 && $b<=255 or finish_error("badnet");
37 $network .= sprintf("%02x",$b);
39 ($val,$mask) = net_valuemask($network,$prefix);
40 printf DEBUG "%08x %08x %08x\n", $val,$mask,~$mask;
41 !($val & ~$mask) or finish_error("badnet");
43 return ($network,$prefix,$val,$mask);
46 sub net_subset ($$$$) {
47 my ($smln,$smlp, $bign,$bigp) = @_;
48 return 0 unless $smlp >= $bigp;
49 ($bigv,$bigm) = net_valuemask($bign,$bigp);
50 ($smlv,$smlm) = net_valuemask($bign,$bigp);
51 return 0 unless ($smlv & $bigm) == $bigv;
55 sub net_overlap ($$$$) {
56 my ($an,$ap, $bn,$bp) = @_;
57 my ($av,$am,$bv,$bm, $tm,$r);
58 ($av,$am) = net_valuemask($an,$ap);
59 ($bv,$bm) = net_valuemask($bn,$bp);
61 $r= (($av & $tm) == ($bv & $tm)) ? 1 : 0;
62 printf DEBUG "overlap %s/%s %s/%s %d\n", $an,$ap, $bn,$bp, $r;
72 if ($sh>=16) { $sh2 += 16; $sh -= 16; }
78 sub net_valuemask ($$) {
79 my ($network,$prefix) = @_;
80 return (hex($network), get_mask($prefix));
83 sub display_net ($$) {
84 my ($network,$prefix) = @_;
85 return join('.', unpack("C4",pack("H8",$network)))."/".$prefix;