Changeset 371


Ignore:
Timestamp:
11/27/07 12:27:45 (16 years ago)
Author:
Kris Deugau
Message:

/trunk

Merge bugfixes and enhancements from /branches/stable r360 through r369

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/cgi-bin/IPDB.pm

    r370 r371  
    1616use DBI;
    1717use Net::SMTP;
     18use NetAddr::IP qw( Compact );
    1819use POSIX;
    1920use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
     
    2425        %disp_alloctypes %list_alloctypes %def_custids @citylist @poplist @masterblocks
    2526        %allocated %free %routed %bigfree %IPDBacl
    26         &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock &deleteBlock
    27         &getBlockData &mailNotify
     27        &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock &addMaster
     28        &deleteBlock &getBlockData &mailNotify
    2829        );
    2930
     
    3334                @masterblocks %allocated %free %routed %bigfree %IPDBacl
    3435                &initIPDBGlobals &connectDB &finish &checkDBSanity &allocateBlock
    35                 &deleteBlock &getBlockData &mailNotify
     36                &addMaster &deleteBlock &getBlockData &mailNotify
    3637                )]
    3738        );
     
    179180#  $dbh->disconnect;
    180181} # 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"
     188sub 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
    181286
    182287
     
    511616      $sth = $dbh->prepare("delete from masterblocks where cidr='$cidr'");
    512617      $sth->execute;
    513       $sth = $dbh->prepare("delete from freeblocks where cidr='$cidr'");
     618      $sth = $dbh->prepare("delete from freeblocks where cidr <<= '$cidr'");
    514619      $sth->execute;
    515620      $dbh->commit;
     
    569674          # contained which have nevertheless been allocated from a container block)
    570675          # 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");
    572677        } else {
    573678          # Standard deallocation.
  • trunk/cgi-bin/extras/db2rwhois.pl

    r341 r371  
    1010# Last update by $Author$
    1111###
    12 # Copyright (C) 2004,2005 - Kris Deugau
     12# Copyright (C) 2004-2007 - Kris Deugau
    1313
    1414use strict;
     
    1717use NetAddr::IP;
    1818use MyIPDB;
     19use File::Path 'rmtree';
    1920
    2021$ENV{"PATH"} = "/bin;/usr/bin";
    2122
    2223my $rwhoisDataPath = "/etc/rwhoisd";
     24
     25my @autharea;
     26my $authrw;
     27# Use the template file to allow us to keep persistent nodes aside from netblock data
     28open AUTHTEMPLATE, "<$rwhoisDataPath/rwhoisd.auth_template";
     29my $template_persist;
     30while (<AUTHTEMPLATE>) {
     31  next if /^##/;
     32  $template_persist = 1 if /^[a-z]/i;
     33  $autharea[0] .= $_;
     34}
    2335
    2436my ($dbh,$msg) = connectDB_My;
     
    3143my %def_custids;
    3244
     45# Get the list of live directories for potential deletion
     46opendir RWHOISROOT, $rwhoisDataPath;
     47my %rwhoisdirs;
     48foreach (readdir RWHOISROOT) {
     49  $rwhoisdirs{$_} = 1 if /^net-/;
     50}
     51closedir RWHOISROOT;
     52
     53# prefetch alloctype data
     54my $sth = $dbh->prepare("select type,def_custid,arin_netname from alloctypes");
     55$sth->execute;
     56while (my @data = $sth->fetchrow_array) {
     57  $netnameprefix{$data[0]} = $data[2];
     58}
     59
     60# Get the list of masters to export
     61my $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.
     68my $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.
     78my $custsth = $dbh->prepare("select name,street,city,province,country,pocode,phone,tech_handle,special ".
     79        "from customers where custid=?");
     80
    3381# Fill in data about our master blocks as allocated from ARIN
    3482# 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.
    3985my $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   }
     86while (my @data = $msth->fetchrow_array()) {
     87
    4788  $masterblocks[$i] = new NetAddr::IP $data[0];
    4889  my ($ctime,undef) = split /\s/, $data[1];
    4990  my ($mtime,undef) = split /\s/, $data[2];
    50 print "$masterblocks[$i] $ctime $mtime\n";
     91
     92  print "$masterblocks[$i] $ctime $mtime\n";
    5193
    5294  my $date;
    5395  chomp ($date = `/bin/date +"%Y-%m-%d"`);
    5496
    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
     120Refresh-Interval: 3600
     121Increment-Interval: 1800
     122Retry-Interval: 1800
     123Time-To-Live: 86400
     124Primary-Server: rwhois.example.com:4321
     125Hostmaster: dns\@example.com
     126);
     127    close SOAFILE;
     128
     129    print "  Creating Schema...\n";
     130    open SCHEMAFILE, ">$netdatadir/schema";
     131    print SCHEMAFILE qq(name: network
     132attributedef: $rwnet/attribute_defs/network.tmpl
     133dbdir: $rwnet/data/network
     134Schema-Version: $serial
     135---
     136name: organization
     137attributedef: $rwnet/attribute_defs/org.tmpl
     138dbdir: $rwnet/data/org
     139description: Organization object
     140Schema-Version: $serial
     141---
     142name: referral
     143attributedef:$rwnet/attribute_defs/referral.tmpl
     144dbdir:$rwnet/data/referral
     145Schema-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]
     155Auth-Area: $masterblocks[$i]
     156Org-Name: Friendly ISP
     157Street-Address: 123 4th Street
     158City: Anytown
     159State: ON
     160Postal-Code: H0H 0H0
     161Country-Code: CA
     162Phone: 000-555-1234
     163Created: 20040308
     164Updated: 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
     176name:$masterblocks[$i]
     177data-dir: $rwnet/data
     178schema-file: $rwnet/schema
     179soa-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";
    60184
    61185  open MASTERFILE,">$rwhoisDataPath/$masterfilename";
     
    77201        "Updated-By: noc\@example.com\n";
    78202
    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) {
    112206
    113207# We get master block info from @masterblocks.
     
    124218 # Updated-By: noc@example.com
    125219
    126   # Get the "full" network number
    127   my $net = new NetAddr::IP $cidr;
     220    # Get the "full" network number
     221    my $net = new NetAddr::IP $cidr;
    128222
    129223# Assumptions:  All data in ipdb is public
    130224# If not, we need another field to indicate "public/private".
    131225
    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 
    142226# cidr custid type city description notes maskbits
    143227
     
    145229if ($desc =~ /^\s*$/) { $desc = 'Friendly ISP'; }
    146230
    147       # Fix up datestamps.  We don't *really* need sub-microsecond resolution on our exports...
    148       ($ctime) = ($ctime =~ /^(\d+-\d+-\d+)\s+/);
    149       ($mtime) = ($mtime =~ /^(\d+-\d+-\d+)\s+/);
     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+/);
    150234
    151235# Notes:
     
    166250#  network:Class-Name:network                   [Provided by rWHOIS protocol]
    167251
    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_-]+)/);
    196276      } 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
    222300  $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
     305foreach 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
     318if ($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
    226346$dbh->disconnect;
  • trunk/cgi-bin/ipdb.psql

    r370 r371  
    3838        "cidr" cidr DEFAULT '255.255.255.255/32' NOT NULL PRIMARY KEY,
    3939        "ctime" timestamp DEFAULT now(),
    40         "mtime" timestamp DEFAULT now()
     40        "mtime" timestamp DEFAULT now(),
     41        "rwhois" character(1) DEFAULT 'n' NOT NULL
    4142);
    4243
     
    111112GRANT ALL on "allocations" to "ipdb";
    112113
    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.notes FROM poolips;
     114CREATE 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;
    114115
    115116REVOKE ALL on "searchme" from PUBLIC;
     
    148149ve      Dynamic VoIP block      Dynamic VoIP block      105     DYN-VOIP        ISP
    149150li      Static IP - LAN/POP     Static LAN/POP IP       190     NOC-VPN ISP
    150 li      Static IP - Management  Static management IP    191     NOC-VPN ISP
     151ai      Static IP - Management  Static management IP    191     NOC-VPN ISP
    151152ld      Static Pool - LAN/POP   LAN pool        195     NOC-VPN ISP
    152 ld      Static Pool - Management        Management pool 196     NOC-VPN ISP
     153ad      Static Pool - Management        Management pool 196     NOC-VPN ISP
    153154in      Internal netblock       Internal netblock       199     6750400 ISP
    154155wc      Reserve for CORE/WAN blocks     CORE/WAN blocks 200     6750400 ISP
     
    159160pr      Dynamic-route DSL netblock      Dynamic-route DSL       221             ISP
    160161ar      ATM block       ATM block       222             ISP
    161 fr      Fibre   Fibre   223             ISP
     162fr      Fibre   Fibre   223     ATM-BUS ISP
    162163rm      Routing Routed netblock 500     6750400 ISP
    163164mm      Master block    Master block    999     6750400 ISP
  • trunk/cgi-bin/main.cgi

    r370 r371  
    8080    print "<div type=heading align=center>Adding $cidr as master block....</div>\n";
    8181
    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') {
    10685      carp "Transaction aborted because $msg";
    107       eval { $ip_dbh->rollback; };
    10886      syslog "err", "Could not add master block '$webvar{cidr}' to database: '$msg'";
    10987      printError("Could not add master block $webvar{cidr} to database: $msg");
  • trunk/cgi-bin/search.cgi

    r370 r371  
    279279#    which probably shouldn't be for reasons of sanity.
    280280
     281  my $cols = "cidr,custid,type,city,description";
     282
    281283  if ($category eq 'all') {
    282284
    283285    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";
    285287    my $count = countRows($sql);
    286288    $sql .= " order by cidr limit $RESULTS_PER_PAGE offset $offset";
     
    293295    # Query for a customer ID.  Note that we can't restrict to "numeric-only"
    294296    # 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%'";
    296298    my $count = countRows($sql);
    297299    $sql .= " order by cidr limit $RESULTS_PER_PAGE offset $offset";
     
    302304    print qq(<div class="heading">Searching for descriptions containing '$query'</div><br>\n);
    303305    # 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%'".
    305307        " or custid ilike '%$query%'";
    306308    my $count = countRows($sql);
     
    320322        # /0->/9 are silly to worry about right now.  I don't think
    321323        # 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'";
    323325        queryResults($sql, $webvar{page}, 1);
    324326      } else {
    325327        #print "Finding all blocks with netmask /$maskbits, leading octet(s) $net<br>\n";
    326328        # 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 ".
    328330                "text(cidr) like '%$maskbits'";
    329331        my $count = countRows($sql);
     
    336338      my ($net,$ip) = ($query =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.)(\d{1,3})/);
    337339      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%'");
    339341      $sth->execute;
    340342      while (my @data = $sth->fetchrow_array()) {
    341343        my $cidr = new NetAddr::IP $data[0];
    342344        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);
    344346        }
    345347      }
    346348    } elsif ($query =~ /^(\d{1,3}\.){1,3}\d{1,3}\.?$/) {
    347349      #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%'";
    349351      my $count = countRows($sql);
    350352      $sql .= " order by cidr limit $RESULTS_PER_PAGE offset $offset";
  • trunk/cgi-bin/snCalc.cgi

    r4 r371  
    33use strict;             
    44use warnings;   
     5use CGI::Carp qw(fatalsToBrowser);
     6use NetAddr::IP;
     7use CommonWeb qw(:ALL);;
    58
    69#file snCalc.cgi        little subnet calculator app
     
    1114print "Content-Type: text/html\n\n";
    1215
    13 open(HTML, "../startsn.html")|| die "Could not open starsn.html :$!";
     16open(HTML, "../startsn.html")|| die "Could not open startsn.html :$!";
    1417my $start = join('', <HTML>);
    1518close(HTML);
    1619print $start;
    1720
    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
     22if ($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;
    2528}
    2629
    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                 );     
     30my $ltinput = $input - 1;
     31my $gtinput = $input + 1;
    4032
    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                 }
     33my $prenet = new NetAddr::IP "0.0.0.0/$ltinput";
     34my $net = new NetAddr::IP "0.0.0.0/$input";
     35my $postnet = new NetAddr::IP "0.0.0.0/$gtinput";
    8636
    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                 }
     37print 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);
    9745
    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                 }
     46print 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
     59print "</td></tr>\n</table>\n";
     60
     61print qq(<input type="button" value="Back" onclick="history.go(-1)" class="heading">
     62</div>
     63</body>
     64</html>
     65);
     66       
     67# Just In Case
     68exit 0;
     69
     70# subs
     71sub 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()
    10884
    10985
    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&nbsp;&nbsp;</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&nbsp;&nbsp;</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});
     86sub 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";
    15196  } else {
    152     $buffer = $ENV{'QUERY_STRING'};
    153     $buffer || read(STDIN, $buffer, $ENV{CONTENT_LENGTH});
     97    $super = new NetAddr::IP "0.0.0.0/24";
    15498  }
    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";
    165101  }
    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  
    5050<td colspan="2">
    5151<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">&nbsp; Show
     54<span class="mask">subnet mask</span>, <span class="wildcard">wildcard mask</span>,
     55and possible subnet ranges for the entered mask length.
    5456</form>
    5557</tr>
  • trunk/ipdb.css

    r279 r371  
    8181        color: red;
    8282}
     83
     84.mask {
     85        background: #00ff00;
     86}
     87
     88.wildcard {
     89        background: #ffff00;
     90}
Note: See TracChangeset for help on using the changeset viewer.