- Timestamp:
- 11/27/07 12:27:45 (17 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cgi-bin/IPDB.pm
r370 r371 16 16 use DBI; 17 17 use Net::SMTP; 18 use NetAddr::IP qw( Compact ); 18 19 use POSIX; 19 20 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); … … 24 25 %disp_alloctypes %list_alloctypes %def_custids @citylist @poplist @masterblocks 25 26 %allocated %free %routed %bigfree %IPDBacl 26 &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock & deleteBlock27 & getBlockData &mailNotify27 &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock &addMaster 28 &deleteBlock &getBlockData &mailNotify 28 29 ); 29 30 … … 33 34 @masterblocks %allocated %free %routed %bigfree %IPDBacl 34 35 &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock 35 & deleteBlock &getBlockData &mailNotify36 &addMaster &deleteBlock &getBlockData &mailNotify 36 37 )] 37 38 ); … … 179 180 # $dbh->disconnect; 180 181 } # end checkDBSanity 182 183 184 ## IPDB::addMaster() 185 # Does all the magic necessary to sucessfully add a master block 186 # Requires database handle, block to add 187 # Returns failure code and error message or success code and "message" 188 sub addMaster { 189 my $dbh = shift; 190 my $cidr = new NetAddr::IP shift; 191 192 # Allow transactions, and raise an exception on errors so we can catch it later. 193 # Use local to make sure these get "reset" properly on exiting this block 194 local $dbh->{AutoCommit} = 0; 195 local $dbh->{RaiseError} = 1; 196 197 # Wrap all the SQL in a transaction 198 eval { 199 my $sth = $dbh->prepare("select count(*) from masterblocks where cidr <<= '$cidr'"); 200 $sth->execute; 201 my @data = $sth->fetchrow_array; 202 203 if ($data[0] eq 0) { 204 # First case - master is brand-spanking-new. 205 ##fixme: rwhois should be globally-flagable somewhere, much like a number of other things 206 ## maybe a db table called "config"? 207 $sth = $dbh->prepare("insert into masterblocks (cidr,rwhois) values ('$cidr','y')"); 208 $sth->execute; 209 210 # Unrouted blocks aren't associated with a city (yet). We don't rely on this 211 # elsewhere though; legacy data may have traps and pitfalls in it to break this. 212 # Thus the "routed" flag. 213 214 $sth = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed)". 215 " values ('$cidr',".$cidr->masklen.",'<NULL>','n')"); 216 $sth->execute; 217 218 # If we get here, everything is happy. Commit changes. 219 $dbh->commit; 220 221 } # new master does not contain existing master(s) 222 else { 223 224 # collect the master(s) we're going to absorb, and snag the longest netmask while we're at it. 225 my $smallmask = $cidr->masklen; 226 $sth = $dbh->prepare("select cidr as mask from masterblocks where cidr <<= '$cidr'"); 227 $sth->execute; 228 my @cmasters; 229 while (my @data = $sth->fetchrow_array) { 230 my $master = new NetAddr::IP $data[0]; 231 push @cmasters, $master; 232 $smallmask = $master->masklen if $master->masklen > $smallmask; 233 } 234 235 # split the new master, and keep only those blocks not part of an existing master 236 my @blocklist; 237 foreach my $seg ($cidr->split($smallmask)) { 238 my $contained = 0; 239 foreach my $master (@cmasters) { 240 $contained = 1 if $master->contains($seg); 241 } 242 push @blocklist, $seg if !$contained; 243 } 244 245 # collect the unrouted free blocks within the new master 246 $sth = $dbh->prepare("select cidr from freeblocks where ". 247 "maskbits>=$smallmask and cidr <<= '$cidr' and routed='n'"); 248 $sth->execute; 249 while (my @data = $sth->fetchrow_array) { 250 my $freeblock = new NetAddr::IP $data[0]; 251 push @blocklist, $freeblock; 252 } 253 254 # combine the set of free blocks we should have now. 255 @blocklist = Compact(@blocklist); 256 257 # and now insert the new data. Make sure to delete old masters too. 258 259 # freeblocks 260 $sth = $dbh->prepare("delete from freeblocks where cidr <<= ?"); 261 my $sth2 = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed) values (?,?,'<NULL>','n')"); 262 foreach my $newblock (@blocklist) { 263 $sth->execute("$newblock"); 264 $sth2->execute("$newblock", $newblock->masklen); 265 } 266 267 # master 268 $sth = $dbh->prepare("delete from masterblocks where cidr <<= '$cidr'"); 269 $sth->execute; 270 $sth = $dbh->prepare("insert into masterblocks (cidr,rwhois) values ('$cidr','y')"); 271 $sth->execute; 272 273 # *whew* If we got here, we likely suceeded. 274 $dbh->commit; 275 } # new master contained existing master(s) 276 }; # end eval 277 278 if ($@) { 279 my $msg = $@; 280 eval { $dbh->rollback; }; 281 return ('FAIL',$msg); 282 } else { 283 return ('OK','OK'); 284 } 285 } # end addMaster 181 286 182 287 … … 511 616 $sth = $dbh->prepare("delete from masterblocks where cidr='$cidr'"); 512 617 $sth->execute; 513 $sth = $dbh->prepare("delete from freeblocks where cidr ='$cidr'");618 $sth = $dbh->prepare("delete from freeblocks where cidr <<= '$cidr'"); 514 619 $sth->execute; 515 620 $dbh->commit; … … 569 674 # contained which have nevertheless been allocated from a container block) 570 675 # We want to make certain that the freeblocks are properly "labelled" 571 $sth = $dbh->prepare("select cidr from freeblocks where cidr <<= '$container' ");676 $sth = $dbh->prepare("select cidr from freeblocks where cidr <<= '$container' order by maskbits desc"); 572 677 } else { 573 678 # Standard deallocation. -
trunk/cgi-bin/extras/db2rwhois.pl
r341 r371 10 10 # Last update by $Author$ 11 11 ### 12 # Copyright (C) 2004 ,2005- Kris Deugau12 # Copyright (C) 2004-2007 - Kris Deugau 13 13 14 14 use strict; … … 17 17 use NetAddr::IP; 18 18 use MyIPDB; 19 use File::Path 'rmtree'; 19 20 20 21 $ENV{"PATH"} = "/bin;/usr/bin"; 21 22 22 23 my $rwhoisDataPath = "/etc/rwhoisd"; 24 25 my @autharea; 26 my $authrw; 27 # Use the template file to allow us to keep persistent nodes aside from netblock data 28 open AUTHTEMPLATE, "<$rwhoisDataPath/rwhoisd.auth_template"; 29 my $template_persist; 30 while (<AUTHTEMPLATE>) { 31 next if /^##/; 32 $template_persist = 1 if /^[a-z]/i; 33 $autharea[0] .= $_; 34 } 23 35 24 36 my ($dbh,$msg) = connectDB_My; … … 31 43 my %def_custids; 32 44 45 # Get the list of live directories for potential deletion 46 opendir RWHOISROOT, $rwhoisDataPath; 47 my %rwhoisdirs; 48 foreach (readdir RWHOISROOT) { 49 $rwhoisdirs{$_} = 1 if /^net-/; 50 } 51 closedir RWHOISROOT; 52 53 # prefetch alloctype data 54 my $sth = $dbh->prepare("select type,def_custid,arin_netname from alloctypes"); 55 $sth->execute; 56 while (my @data = $sth->fetchrow_array) { 57 $netnameprefix{$data[0]} = $data[2]; 58 } 59 60 # Get the list of masters to export 61 my $msth = $dbh->prepare("select cidr,ctime,mtime from masterblocks where rwhois='y'"); 62 $msth->execute; 63 64 # Prepare to select subblocks for each master 65 # Make sure to remove the private netblocks from this, 66 # no use or point in broadcasting our use of them. 67 # Also remove the details of our "reserved CORE/WAN" blocks; they're not critical. 68 my $ssth = $dbh->prepare("select cidr,custid,type,city,description,createstamp,modifystamp,swip ". 69 "from allocations where ". 70 "not (cidr <<= '192.168.0.0/16') and ". 71 "not (cidr <<= '172.16.0.0/12') and ". 72 "not (cidr <<= '10.0.0.0/8') and ". 73 "not (type = 'wr') and ". 74 "masklen(cidr) <=30 and ". 75 "cidr <<= ?"); 76 77 # Customer data, for those rare blocks we really need to delegate. 78 my $custsth = $dbh->prepare("select name,street,city,province,country,pocode,phone,tech_handle,special ". 79 "from customers where custid=?"); 80 33 81 # Fill in data about our master blocks as allocated from ARIN 34 82 # We open separate files for each of these as appropriate. 35 # Note that this ASS-U-MEs that we do not add master IP blocks- 36 # there should probably be a separate system for doing that. 37 my $sth = $dbh->prepare("select cidr,ctime,mtime from masterblocks;"); 38 $sth->execute; 83 # Changes in master blocks are treated as complete new masters - since we're exporting 84 # all data every time, this isn't so terrible as it might seem. 39 85 my $i=0; 40 GETMASTERS: while (my @data = $sth->fetchrow_array()) { 41 42 # Techically, we only need to exclude 204.138.172.0/24, as we "own" all of the other blocks. 43 # However, 205.207.184.0/23 and 206.130.64.0/24 are, um, awkward. 44 if ($data[0] =~ /^(192.168.0.0|172.16.0.0|10.0.0.0|20[456])/) { 45 next GETMASTERS; 46 } 86 while (my @data = $msth->fetchrow_array()) { 87 47 88 $masterblocks[$i] = new NetAddr::IP $data[0]; 48 89 my ($ctime,undef) = split /\s/, $data[1]; 49 90 my ($mtime,undef) = split /\s/, $data[2]; 50 print "$masterblocks[$i] $ctime $mtime\n"; 91 92 print "$masterblocks[$i] $ctime $mtime\n"; 51 93 52 94 my $date; 53 95 chomp ($date = `/bin/date +"%Y-%m-%d"`); 54 96 55 # Whew! Ugly little varmint. 56 my $masterfilename = "net-".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen. 57 "/data/network/".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen.".txt"; 58 59 # Need check here to create tree for netblock? 97 my $rwnet = "net-".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen; 98 99 # unflag the directory for deletion. Whee! Roundabout! 100 delete $rwhoisdirs{$rwnet}; 101 102 # Hokay. Gonna do checks *here* to see if we need to create new master trees 103 my $netdatadir = "$rwhoisDataPath/$rwnet"; 104 if (! -e $netdatadir) { 105 print " New master $masterblocks[$i]!\n"; 106 print " Creating directories...\n"; 107 mkdir $netdatadir; 108 mkdir "$netdatadir/attribute_defs"; 109 mkdir "$netdatadir/data"; 110 mkdir "$netdatadir/data/network"; 111 mkdir "$netdatadir/data/org"; 112 mkdir "$netdatadir/data/referral"; 113 114 my $serial; 115 chomp ($serial = `/bin/date '+%Y%m%d'000000000`); 116 117 print " Creating SOA...\n"; 118 open SOAFILE, ">$netdatadir/soa"; 119 print SOAFILE qq(Serial-Number: $serial 120 Refresh-Interval: 3600 121 Increment-Interval: 1800 122 Retry-Interval: 1800 123 Time-To-Live: 86400 124 Primary-Server: rwhois.example.com:4321 125 Hostmaster: dns\@example.com 126 ); 127 close SOAFILE; 128 129 print " Creating Schema...\n"; 130 open SCHEMAFILE, ">$netdatadir/schema"; 131 print SCHEMAFILE qq(name: network 132 attributedef: $rwnet/attribute_defs/network.tmpl 133 dbdir: $rwnet/data/network 134 Schema-Version: $serial 135 --- 136 name: organization 137 attributedef: $rwnet/attribute_defs/org.tmpl 138 dbdir: $rwnet/data/org 139 description: Organization object 140 Schema-Version: $serial 141 --- 142 name: referral 143 attributedef:$rwnet/attribute_defs/referral.tmpl 144 dbdir:$rwnet/data/referral 145 Schema-Version: $serial 146 ); 147 close SCHEMAFILE; 148 149 print " Copying template files...\n"; 150 qx { /bin/cp $rwhoisDataPath/skel/attribute_defs/* $netdatadir/attribute_defs/ }; 151 152 print " Creating org data...\n"; 153 open ORGDATAFILE, ">$netdatadir/data/org/friendlyisp.txt"; 154 print ORGDATAFILE qq(ID: NETBLK-ISP.$masterblocks[$i] 155 Auth-Area: $masterblocks[$i] 156 Org-Name: Friendly ISP 157 Street-Address: 123 4th Street 158 City: Anytown 159 State: ON 160 Postal-Code: H0H 0H0 161 Country-Code: CA 162 Phone: 000-555-1234 163 Created: 20040308 164 Updated: 20040308 165 ); 166 close ORGDATAFILE; 167 168 # Generate auth_area record, and add it to the array. 169 $authrw = 1; # Flag for rewrite and daemon reload/restart 170 171 } # new master 172 173 # do this for all masters, so that we can use this array to export the data 174 # to rwhoisd.auth_area later if we need to 175 push @autharea, qq(type:master 176 name:$masterblocks[$i] 177 data-dir: $rwnet/data 178 schema-file: $rwnet/schema 179 soa-file: $rwnet/soa 180 ); 181 182 # Recreate the net-nnn.nnn.nnn.nnn-nn.txt data file 183 my $masterfilename = "$rwnet/data/network/".$masterblocks[$i]->addr."-".$masterblocks[$i]->masklen.".txt"; 60 184 61 185 open MASTERFILE,">$rwhoisDataPath/$masterfilename"; … … 77 201 "Updated-By: noc\@example.com\n"; 78 202 79 close MASTERFILE; 80 $i++; 81 } 82 83 # prefetch alloctype data 84 $sth = $dbh->prepare("select type,def_custid,arin_netname from alloctypes"); 85 $sth->execute; 86 while (my @data = $sth->fetchrow_array) { 87 $netnameprefix{$data[0]} = $data[2]; 88 $def_custids{$data[0]} = $data[1]; 89 } 90 91 # Now read out the data in the "main" delegation list, and check it 92 # with the master blocks. We need to do this to decide which rWHOIS 93 # "net-xxx.xxx.xxx.xxx-mask" tree the data belongs in. 94 95 # Make sure to remove the private netblocks from this. 96 # No use or point in broadcasting our use of them. 97 # Also remove the details of our "reserved CORE/WAN" blocks; they're not critical. 98 $sth = $dbh->prepare("select cidr,custid,type,city,description,createstamp,modifystamp,swip ". 99 "from allocations where ". 100 "not (cidr <<= '192.168.0.0/16') and ". 101 "not (cidr <<= '172.16.0.0/12') and ". 102 "not (cidr <<= '10.0.0.0/8') and ". 103 "not (type = 'wr') and ". 104 "masklen(cidr) <=30"); 105 #" and (custid='6750400' or custid like '%-RES' or custid like '%-BUS')"); 106 $sth->execute; 107 108 my $custsth = $dbh->prepare("select name,street,city,province,country,pocode,phone,tech_handle,special from customers where custid=?"); 109 110 $i=0; 111 while (my ($cidr, $custid, $type, $city, $desc, $ctime, $mtime, $swip) = $sth->fetchrow_array) { 203 # And now the subblocks 204 $ssth->execute("$masterblocks[$i]"); 205 while (my ($cidr, $custid, $type, $city, $desc, $ctime, $mtime, $swip) = $ssth->fetchrow_array) { 112 206 113 207 # We get master block info from @masterblocks. … … 124 218 # Updated-By: noc@example.com 125 219 126 # Get the "full" network number127 my $net = new NetAddr::IP $cidr;220 # Get the "full" network number 221 my $net = new NetAddr::IP $cidr; 128 222 129 223 # Assumptions: All data in ipdb is public 130 224 # If not, we need another field to indicate "public/private". 131 225 132 foreach my $master (@masterblocks) {133 if ($master->contains($net)) {134 135 # Whew! Ugly little varmint.136 my $masterfilename = "net-".$master->addr."-".$master->masklen.137 "/data/network/".$master->addr."-".$master->masklen.".txt";138 139 open MASTERFILE,">>$rwhoisDataPath/$masterfilename"140 or print "File open error: '$!' on '$rwhoisDataPath/$masterfilename'\n";141 142 226 # cidr custid type city description notes maskbits 143 227 … … 145 229 if ($desc =~ /^\s*$/) { $desc = 'Friendly ISP'; } 146 230 147 148 149 231 # Fix up datestamps. We don't *really* need sub-microsecond resolution on our exports... 232 ($ctime) = ($ctime =~ /^(\d+-\d+-\d+)\s+/); 233 ($mtime) = ($mtime =~ /^(\d+-\d+-\d+)\s+/); 150 234 151 235 # Notes: … … 166 250 # network:Class-Name:network [Provided by rWHOIS protocol] 167 251 168 my $netname = $netnameprefix{$type}; 169 170 if ($swip eq 'y' && $def_custids{$type} eq '') { 171 # def_custids{$type} should only be blank on types that are 172 # allocated direct to customers. i are sMart!!11!!oneone! 173 $custsth->execute($custid); 174 my ($name, $street, $city, $prov, $country, $pocode, $phone, $tech, $special) = $custsth->fetchrow_array; 175 $custsth->finish; 176 if ($special && $special =~ /NetName/ && $special =~ /$cidr/) { 177 ($netname) = ($special =~ /NetName$cidr: ([A-Z0-9_-]+)/); 178 } else { 179 $netname .= "-".$net->network; 180 } 181 print MASTERFILE "---\nID: NETBLK-ISP.$master\n". 182 "Auth-Area: $master\n". 183 "Network-Name: $netname\n". 184 "IP-Network: $net\n". 185 "IP-Network-Block: ".$net->range."\n". 186 "Org-Name: $name\n". 187 "Street-Address: $street\n". 188 "City: $city\n". 189 "StateProv: $prov\n". 190 "Postal-Code: $pocode\n". 191 "Country-Code: $country\n". 192 "Tech-Contact: $tech\n". 193 "Created: $ctime\n". 194 "Updated: $mtime\n". 195 "Updated-By: noc\@example.com\n"; 252 my $netname = $netnameprefix{$type}; 253 254 if ($swip eq 'n') { 255 print MASTERFILE "---\nID: NETBLK-ISP.$masterblocks[$i]\n". 256 "Auth-Area: $masterblocks[$i]\n". 257 "Network-Name: $netname-".$net->network."\n". 258 "IP-Network: $net\n". 259 "IP-Network-Block: ".$net->range."\n". 260 "Org-Name: Friendly ISP\n". 261 "Street-Address: 123 4th Street\n". 262 "City: Anytown\n". 263 "StateProv: Ontario\n". 264 "Postal-Code: H0H 0H0\n". 265 "Country-Code: CA\n". 266 "Tech-Contact: ISP-ARIN-HANDLE\n". 267 "Created: $ctime\n". 268 "Updated: $mtime\n". 269 "Updated-By: noc\@example.com\n"; 270 } else { 271 $custsth->execute($custid); 272 my ($name, $street, $city, $prov, $country, $pocode, $phone, $tech, $special) = $custsth->fetchrow_array; 273 $custsth->finish; 274 if ($special && $special =~ /NetName/ && $special =~ /$cidr/) { 275 ($netname) = ($special =~ /NetName$cidr: ([A-Z0-9_-]+)/); 196 276 } else { 197 print MASTERFILE "---\nID: NETBLK-ISP.$master\n". 198 "Auth-Area: $master\n". 199 "Network-Name: $netname-".$net->network."\n". 200 "IP-Network: $net\n". 201 "IP-Network-Block: ".$net->range."\n". 202 "Org-Name: Friendly ISP\n". 203 "Street-Address: 123 4th Street\n". 204 "City: Anytown\n". 205 "StateProv: Ontario\n". 206 "Postal-Code: H0H 0H0\n". 207 "Country-Code: CA\n". 208 "Tech-Contact: ISP-ARIN-HANDLE\n". 209 "Created: $ctime\n". 210 "Updated: $mtime\n". 211 "Updated-By: noc\@example.com\n"; 212 } # decide which contact data to use (cust data only on swip==y && def custid=='') 213 } # net in master 214 } # foreach master 215 216 217 218 # print "$data[0]\t| $data[1]\t| $data[2]\t| $data[3]\t| $data[4]\t| ". 219 # "$data[5]\t| $data[6]\t| $data[7]\t| $data[8]\t| $data[9]\n"; 220 # print "$data[0]\t| $data[1]\t| $data[2]\t| $data[3]\t| $data[4]\t| ". 221 # "$data[5]\t| $data[6]\t| $data[7]\t| $data[8]\n"; 277 $netname .= "-".$net->network; 278 } 279 print MASTERFILE "---\nID: NETBLK-ISP.$masterblocks[$i]\n". 280 "Auth-Area: $masterblocks[$i]\n". 281 "Network-Name: $netname\n". 282 "IP-Network: $net\n". 283 "IP-Network-Block: ".$net->range."\n". 284 "Org-Name: $name\n". 285 "Street-Address: $street\n". 286 "City: $city\n". 287 "StateProv: $prov\n". 288 "Postal-Code: $pocode\n". 289 "Country-Code: $country\n". 290 "Tech-Contact: $tech\n". 291 "Created: $ctime\n". 292 "Updated: $mtime\n". 293 "Updated-By: noc\@example.com\n"; 294 } # swip 295 296 } # while $ssth->fetchrow_array() 297 298 close MASTERFILE; 299 222 300 $i++; 223 } # while fetchrow_array() 224 225 301 } # while $msth->fetchrow_array() 302 303 # Now we see if there's obsolete netdata directories to be deleted, 304 # and therefore an auth-area file to regenerate 305 foreach my $netdir (keys %rwhoisdirs) { 306 print "deleting obsolete directory $netdir...\n"; 307 rmtree ( "$rwhoisDataPath/$netdir", { verbose => 1, error => \my $errlist } ); 308 for my $diag (@$errlist) { 309 my ($file, $message) = each %$diag; 310 if ($file eq '') { 311 print "general error: $message\n"; 312 } 313 } 314 $authrw = 1; # there's probably a more efficient place to put this. Feh. 315 } 316 317 # Regenerate rwhoisd.auth_area if needed 318 if ($authrw) { 319 print "Regenerating auth_area\n"; 320 open RWHOISDAUTH, ">$rwhoisDataPath/rwhoisd.auth_area"; 321 print RWHOISDAUTH "# WARNING: This file is autogenerated! Any static nodes should\n". 322 "# be entered in /etc/rwhoisd/rwhoisd.auth_template\n"; 323 if ($template_persist) { 324 print RWHOISDAUTH shift @autharea; 325 print RWHOISDAUTH "---\n"; 326 } 327 # feh. we need to know when we're at the end of the loop, because then 328 # we DON'T want to write the separator... 329 for (;@autharea;) { # my head hurts. 330 print RWHOISDAUTH shift @autharea; 331 print RWHOISDAUTH "---\n" if @autharea; 332 } 333 close RWHOISDAUTH; 334 335 # restart/reload rwhoisd 336 if (-e "$rwhoisDataPath/rwhoisd.pid") { # no pidfile, no restart. 337 print "Restarting rwhoisd\n"; 338 open PIDFILE, "<$rwhoisDataPath/rwhoisd.pid"; 339 my ($rwpid) = (<PIDFILE> =~ /^(\d+)/); 340 close PIDFILE; 341 kill 'HUP', $rwpid; 342 } 343 } 344 345 # and finally 226 346 $dbh->disconnect; -
trunk/cgi-bin/ipdb.psql
r370 r371 38 38 "cidr" cidr DEFAULT '255.255.255.255/32' NOT NULL PRIMARY KEY, 39 39 "ctime" timestamp DEFAULT now(), 40 "mtime" timestamp DEFAULT now() 40 "mtime" timestamp DEFAULT now(), 41 "rwhois" character(1) DEFAULT 'n' NOT NULL 41 42 ); 42 43 … … 111 112 GRANT ALL on "allocations" to "ipdb"; 112 113 113 CREATE VIEW "searchme" as SELECT allocations.cidr, allocations.custid, allocations."type", allocations.city, allocations.description, allocations.notes FROM allocations UNION SELECT poolips.ip, poolips.custid, poolips.type, poolips.city, poolips.description, poolips.notesFROM poolips;114 CREATE VIEW "searchme" as SELECT allocations.cidr, allocations.custid, allocations."type", allocations.city, allocations.description, allocations.notes, allocations.oldcustid, allocations.circuitid FROM allocations UNION SELECT poolips.ip, poolips.custid, poolips.type, poolips.city, poolips.description, poolips.notes, poolips.oldcustid, poolips.circuitid FROM poolips; 114 115 115 116 REVOKE ALL on "searchme" from PUBLIC; … … 148 149 ve Dynamic VoIP block Dynamic VoIP block 105 DYN-VOIP ISP 149 150 li Static IP - LAN/POP Static LAN/POP IP 190 NOC-VPN ISP 150 li Static IP - Management Static management IP 191 NOC-VPN ISP151 ai Static IP - Management Static management IP 191 NOC-VPN ISP 151 152 ld Static Pool - LAN/POP LAN pool 195 NOC-VPN ISP 152 ld Static Pool - Management Management pool 196 NOC-VPN ISP153 ad Static Pool - Management Management pool 196 NOC-VPN ISP 153 154 in Internal netblock Internal netblock 199 6750400 ISP 154 155 wc Reserve for CORE/WAN blocks CORE/WAN blocks 200 6750400 ISP … … 159 160 pr Dynamic-route DSL netblock Dynamic-route DSL 221 ISP 160 161 ar ATM block ATM block 222 ISP 161 fr Fibre Fibre 223 ISP162 fr Fibre Fibre 223 ATM-BUS ISP 162 163 rm Routing Routed netblock 500 6750400 ISP 163 164 mm Master block Master block 999 6750400 ISP -
trunk/cgi-bin/main.cgi
r370 r371 80 80 print "<div type=heading align=center>Adding $cidr as master block....</div>\n"; 81 81 82 # Allow transactions, and raise an exception on errors so we can catch it later. 83 # Use local to make sure these get "reset" properly on exiting this block 84 local $ip_dbh->{AutoCommit} = 0; 85 local $ip_dbh->{RaiseError} = 1; 86 87 # Wrap the SQL in a transaction 88 eval { 89 $sth = $ip_dbh->prepare("insert into masterblocks values ('$webvar{cidr}')"); 90 $sth->execute; 91 92 # Unrouted blocks aren't associated with a city (yet). We don't rely on this 93 # elsewhere though; legacy data may have traps and pitfalls in it to break this. 94 # Thus the "routed" flag. 95 96 $sth = $ip_dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed)". 97 " values ('$webvar{cidr}',".$cidr->masklen.",'<NULL>','n')"); 98 $sth->execute; 99 100 # If we get here, everything is happy. Commit changes. 101 $ip_dbh->commit; 102 }; # end eval 103 104 if ($@) { 105 my $msg = $@; 82 my ($code,$msg) = addMaster($ip_dbh, $webvar{cidr}); 83 84 if ($code eq 'FAIL') { 106 85 carp "Transaction aborted because $msg"; 107 eval { $ip_dbh->rollback; };108 86 syslog "err", "Could not add master block '$webvar{cidr}' to database: '$msg'"; 109 87 printError("Could not add master block $webvar{cidr} to database: $msg"); -
trunk/cgi-bin/search.cgi
r370 r371 279 279 # which probably shouldn't be for reasons of sanity. 280 280 281 my $cols = "cidr,custid,type,city,description"; 282 281 283 if ($category eq 'all') { 282 284 283 285 print qq(<div class="heading">Showing all netblock and static-IP allocations</div><br>\n); 284 $sql = "select *from searchme";286 $sql = "select $cols from searchme"; 285 287 my $count = countRows($sql); 286 288 $sql .= " order by cidr limit $RESULTS_PER_PAGE offset $offset"; … … 293 295 # Query for a customer ID. Note that we can't restrict to "numeric-only" 294 296 # as we have non-numeric custIDs in the legacy data. :/ 295 $sql = "select *from searchme where custid ilike '%$query%' or oldcustid ilike '%$query%'";297 $sql = "select $cols from searchme where custid ilike '%$query%' or oldcustid ilike '%$query%'"; 296 298 my $count = countRows($sql); 297 299 $sql .= " order by cidr limit $RESULTS_PER_PAGE offset $offset"; … … 302 304 print qq(<div class="heading">Searching for descriptions containing '$query'</div><br>\n); 303 305 # Query based on description (includes "name" from old DB). 304 $sql = "select *from searchme where description ilike '%$query%'".306 $sql = "select $cols from searchme where description ilike '%$query%'". 305 307 " or custid ilike '%$query%'"; 306 308 my $count = countRows($sql); … … 320 322 # /0->/9 are silly to worry about right now. I don't think 321 323 # we'll be getting a class A anytime soon. <g> 322 $sql = "select *from searchme where cidr='$query'";324 $sql = "select $cols from searchme where cidr='$query'"; 323 325 queryResults($sql, $webvar{page}, 1); 324 326 } else { 325 327 #print "Finding all blocks with netmask /$maskbits, leading octet(s) $net<br>\n"; 326 328 # Partial match; beginning of subnet and maskbits are provided 327 $sql = "select *from searchme where text(cidr) like '$net%' and ".329 $sql = "select $cols from searchme where text(cidr) like '$net%' and ". 328 330 "text(cidr) like '%$maskbits'"; 329 331 my $count = countRows($sql); … … 336 338 my ($net,$ip) = ($query =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.)(\d{1,3})/); 337 339 my $sfor = new NetAddr::IP $query; 338 $sth = $ip_dbh->prepare("select *from searchme where text(cidr) like '$net%'");340 $sth = $ip_dbh->prepare("select $cols from searchme where text(cidr) like '$net%'"); 339 341 $sth->execute; 340 342 while (my @data = $sth->fetchrow_array()) { 341 343 my $cidr = new NetAddr::IP $data[0]; 342 344 if ($cidr->contains($sfor)) { 343 queryResults("select *from searchme where cidr='$cidr'", $webvar{page}, 1);345 queryResults("select $cols from searchme where cidr='$cidr'", $webvar{page}, 1); 344 346 } 345 347 } 346 348 } elsif ($query =~ /^(\d{1,3}\.){1,3}\d{1,3}\.?$/) { 347 349 #print "Finding matches with leading octet(s) $query<br>\n"; 348 $sql = "select *from searchme where text(cidr) like '$query%'";350 $sql = "select $cols from searchme where text(cidr) like '$query%'"; 349 351 my $count = countRows($sql); 350 352 $sql .= " order by cidr limit $RESULTS_PER_PAGE offset $offset"; -
trunk/cgi-bin/snCalc.cgi
r4 r371 3 3 use strict; 4 4 use warnings; 5 use CGI::Carp qw(fatalsToBrowser); 6 use NetAddr::IP; 7 use CommonWeb qw(:ALL);; 5 8 6 9 #file snCalc.cgi little subnet calculator app … … 11 14 print "Content-Type: text/html\n\n"; 12 15 13 open(HTML, "../startsn.html")|| die "Could not open star sn.html :$!";16 open(HTML, "../startsn.html")|| die "Could not open startsn.html :$!"; 14 17 my $start = join('', <HTML>); 15 18 close(HTML); 16 19 print $start; 17 20 18 if($webvar{input} =~ m/(\/\d\d)/) 19 {20 $input =$1;21 } 22 else 23 {24 $input = '/29';21 # Clean up input so we don't divide by zero or something equally silly 22 if ($webvar{input} =~ m/(\d+)/) { 23 $input = 1*$1; 24 $input = 3 if $input < 3; 25 $input = 29 if $input > 29; # Not doing IPv6 yet... 26 } else { 27 $input = 29; 25 28 } 26 29 27 if(substr($input, 1, 2) > 32 || substr($input, 1, 2) < 24) 28 { 29 printAndExit("'$input' is an invalid netmask."); 30 } 31 else 32 { $input = substr($input, 1, 2); 33 my $ltinput = $input -1; 34 my $gtinput = $input +1; 35 36 print qq( <div class="center"> 37 <table align="center" cellspacing="3" cellpadding="3"><tr> 38 <td class="heading" align="center"> Results for /$ltinput</td><td class="heading" align="center"> Results for /$input</td><td class="heading" align="center"> Results for /$gtinput</td></tr> 39 ); 30 my $ltinput = $input - 1; 31 my $gtinput = $input + 1; 40 32 41 if( $input =~ m|.*24.*|){ 42 $input = 256; 43 $ltinput =128; 44 undef($gtinput); 45 } 46 elsif( $input =~ m|.*25.*|){ 47 $input = 128; 48 $ltinput = 64; 49 $gtinput = 256; 50 } 51 elsif( $input =~ m|.*26.*|){ 52 $input = 64; 53 $ltinput = 32; 54 $gtinput = 128; 55 } 56 elsif( $input =~ m|.*27.*|){ 57 $input = 32; 58 $ltinput = 16; 59 $gtinput = 64; 60 } 61 elsif( $input =~ m|.*28.*|){ 62 $input = 16; 63 $ltinput = 8; 64 $gtinput = 32; 65 } 66 elsif( $input =~ m|.*29.*|){ 67 $input = 8; 68 $ltinput = 4; 69 $gtinput = 16; 70 } 71 elsif( $input =~ m|.*30.*|){ 72 $input = 4; 73 $ltinput = 2; 74 $gtinput = 8; 75 } 76 elsif( $input =~ m|.*31.*|){ 77 $input = 2; 78 $ltinput = 1; 79 $gtinput = 4; 80 } 81 elsif( $input =~ m|.*32.*|){ 82 $input = 1; 83 $gtinput = 2; 84 undef($ltinput); 85 } 33 my $prenet = new NetAddr::IP "0.0.0.0/$ltinput"; 34 my $net = new NetAddr::IP "0.0.0.0/$input"; 35 my $postnet = new NetAddr::IP "0.0.0.0/$gtinput"; 86 36 87 my ($center, $left, $right) = ('','',''); 88 my $subnet; 89 90 #add the subnet masks 91 92 if($input) 93 { 94 $subnet = 256 - $input; 95 $center = qq(<div style="background-color: #00ff00">255.255.255.$subnet </div>); 96 } 37 print qq(<div class="center"> 38 <table align="center" cellspacing="3" cellpadding="3"> 39 <tr> 40 <td class="heading" align="center">Results for /$ltinput</td> 41 <td class="heading" align="center">Results for /$input</td> 42 <td class="heading" align="center">Results for /$gtinput</td> 43 </tr> 44 ); 97 45 98 if($ltinput) 99 { 100 $subnet = 256 - $ltinput; 101 $right = qq(<div style="background-color: #00ff00">255.255.255.$subnet</div>); 102 } 103 if($gtinput) 104 { 105 $subnet = 256 - $gtinput; 106 $left = qq(<div style="background-color: #00ff00">255.255.255.$subnet</div>); 107 } 46 print qq(<tr><td valign="top">\n). 47 qq( <div class="mask">).$prenet->mask."</div>\n". 48 qq( <div class="wildcard">).$prenet->wildcard."</div>\n". 49 getranges($ltinput). 50 qq(</td>\n<td valign="top" bgcolor="#d0e0e0">\n). 51 qq( <div class="mask">).$net->mask."</div>\n". 52 qq( <div class="wildcard">).$net->wildcard."</div>\n". 53 getranges($input). 54 qq(</td>\n<td valign="top">). 55 qq( <div class="mask">).$postnet->mask."</div>\n". 56 qq( <div class="wildcard">).$postnet->wildcard."</div>\n". 57 getranges($gtinput); 58 59 print "</td></tr>\n</table>\n"; 60 61 print qq(<input type="button" value="Back" onclick="history.go(-1)" class="heading"> 62 </div> 63 </body> 64 </html> 65 ); 66 67 # Just In Case 68 exit 0; 69 70 # subs 71 sub xrange { 72 my $block = shift; 73 my $masklen = shift; 74 my $data = $block->range; 75 if ($masklen >= 24) { 76 $data =~ s/\b0\.0\.0\./x.x.x./g; 77 } elsif ($masklen >=16) { 78 $data =~ s/\b0\.0\.(\d+\.\d+)/x.x.$1/g; 79 } elsif ($masklen >=8) { 80 $data =~ s/\b0\.(\d+\.\d+\.\d+)/x.$1/g; 81 } 82 return $data; 83 } # xrange() 108 84 109 85 110 for(my $i = 0; $i < 256; $i++) 111 { 112 #left display -- one less than requested 113 if(defined($gtinput) && $i % $gtinput == 0) 114 { 115 my $upper = $i + $gtinput -1; 116 $left .= "x.x.x.$i - x.x.x.$upper</br>\n"; 117 } 118 119 #center display -- the one requested 120 if($i % $input == 0 ) 121 { 122 my $upper = $i + $input - 1; 123 $center .= "x.x.x.$i - x.x.x.$upper </br>\n"; 124 } 125 126 #right display -- one more than requested 127 if(defined($ltinput) && $i % $ltinput == 0) 128 { 129 my $upper = $i + $ltinput -1; 130 $right .= "x.x.x.$i - x.x.x.$upper </br>\n"; 131 } 132 } 133 134 print qq(<tr><td valign="top" >$left</td> 135 <td valign="top" bgcolor="#d0e0e0">$center</td> 136 <td valign="top" >$right</td></tr> 137 ); 138 print "</table>\n"; 139 140 print '<input type="button" value="Back" onclick="history.go(-1)" class="heading"></div></body></html>'; 141 142 } 143 144 145 sub parse_post { 146 my $buffer; 147 if ($ENV{'REQUEST_METHOD'} eq "GET") { 148 $buffer=$ENV{'QUERY_STRING'} 149 } elsif ($ENV{'REQUEST_METHOD'} eq 'POST' && $ENV{'CONTENT_TYPE'} eq "application/x-www-form-urlencoded") { 150 read(STDIN, $buffer, $ENV{CONTENT_LENGTH}); 86 sub getranges { 87 my $masklen = shift; 88 my $ret = ''; 89 my $super; 90 if ($masklen < 8) { 91 $super = new NetAddr::IP "0.0.0.0/0"; 92 } elsif ($masklen < 16) { 93 $super = new NetAddr::IP "0.0.0.0/8"; 94 } elsif ($masklen < 24) { 95 $super = new NetAddr::IP "0.0.0.0/16"; 151 96 } else { 152 $buffer = $ENV{'QUERY_STRING'}; 153 $buffer || read(STDIN, $buffer, $ENV{CONTENT_LENGTH}); 97 $super = new NetAddr::IP "0.0.0.0/24"; 154 98 } 155 my @pairs = split(/&/, $buffer); 156 my %webvarLocal; 157 foreach my $pair (@pairs) { 158 my ($name, $value) = split(/=/, $pair); 159 $name =~ tr/+/ /; 160 $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 161 $value =~ tr/+/ /; 162 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 163 $value =~ s/\'/\\\'/g; 164 $webvarLocal{$name} = $value; 99 foreach my $net ($super->split($masklen)) { 100 $ret .= "\t".xrange($net,$masklen)."<br />\n"; 165 101 } 166 return %webvarLocal; 167 } 168 sub printAndExit 169 { 170 my $errStr = $_[0]; 171 print qq( 172 <center><p class="regular"> $errStr </p> 173 <input type="button" value="Back" onclick="history.go(-1)" class="heading"> 174 </center> 175 ); 176 exit(0); 177 } 102 return $ret; 103 } # getranges() -
trunk/help.html
r370 r371 50 50 <td colspan="2"> 51 51 <form method="POST" action="cgi-bin/snCalc.cgi"> 52 <input type="text" size="5" maxlength="10" name="input" class="regular"> 53 <input type="submit" value="Calculate" class="heading"> 52 / <input type="text" size="5" maxlength="10" name="input" class="regular"> 53 <input type="submit" value="Calculate" class="heading"> Show 54 <span class="mask">subnet mask</span>, <span class="wildcard">wildcard mask</span>, 55 and possible subnet ranges for the entered mask length. 54 56 </form> 55 57 </tr> -
trunk/ipdb.css
r279 r371 81 81 color: red; 82 82 } 83 84 .mask { 85 background: #00ff00; 86 } 87 88 .wildcard { 89 background: #ffff00; 90 }
Note:
See TracChangeset
for help on using the changeset viewer.