Skip to content
Mar 9 / Greg

IPPlan and RWhois Integration Script

Pull all of your records from IPPlan and insert them into your RWhois server automatically.

If you are an ISP or large enterprise you will need to keep up with your addressing and assignments somehow, right? There are only a handful of products out there that will do this. The company I work for is an ISP, so my favorite address manager is IPPlan. It is really tailored to ISPs.

It’s:

  • Web-based
  • Opensource/Free
  • Easy to use
  • Ugly graphics, not that I mind!

If you are an ISP, in the USA, then you own a chunk of addressing from ARIN. When handing this addressing out, you are required by ARIN to add an entry either to their Rwhois server or your own for every allocation that is larger than a /30. So, if you hand someone a block of 8 or larger, you have to have an entry. On top of that, they want you to have the updates in within 7 days of the allocation. Keeping up with this can be cumbersome. IPPlan can generate Swips to email to ARIN for updating, but you have to create a new “customer” in IPPlan every time you want to do an allocation for the swips to work properly…a HUGE pain.

ARIN has a nice little RWhois server you can run on your own server to manage your reverse records. It is all command line and there is no convenient way to administer this guy.

My solution:

I wrote a PHP script that queries the IPPlan database for each allocation that is larger than a /30. It takes the allocation and the description field and builds the text files necessary for the RWhois server and saves them to a folder on itself. Rather than creating a new customer for each allocation, I just use the description field; this cuts down a two minute process to about 10 seconds. Then, it deletes the old RWhois files on the RWhois server and FTPs the new ones over. The RWhois service is then restarted and it indexes all the new information. I schedule all this to run once a week to be in compliance with ARIN.

For all the code and details, click below!!!

IPPlan Server

I’m having all the config files go into the /root/rwhois folder. They will end up in folders called net1, net2 and so on. The supernet will have a file that you will have to create yourself and place inside the rwhois folder. The delete script on the rwhois server will delete all files, and this supernet file isn’t auto generated by the script, so you need to create it so the script can copy it at run time.

Supernet file looks like the following (200.0.0.0-21.txt):

ID: NETBLK-MNSL-200.0.0.0/21
Auth-Area: 200.0.0.0/21
Network-Name: MNS-BLK-1-200.0.0.0/21
IP-Network: 200.0.0.0/21
IP-Network-Block: 200.0.0.0 – 200.0.7.255
Organization: GregSowell, Inc.
Tech-Contact: [email protected]
Admin-Contact: DNSADGregSowell-ARIN

You will have to adjust the files for your information. You need one of these for each of the allocations you have from ARIN. This is the only file you have to generate, the script will produce all of the smaller ones.

This script does all the work for us. He parses all the DB info. You will need to replace all of my information with yours.


4) {
//One for each of your supernets
//this is in the format of starting IP address, then ending IP address
if ($row['baseaddr'] > ip2long("200.0.0.0") and $row['baseaddr'] < ip2long("200.0.7.255")) {//net1 $netFolder = "/root/rwhois/net1/"; } if ($row['baseaddr'] > ip2long("210.0.0.0") and $row['baseaddr'] < ip2long("210.0.15.255")) {//net2 $netFolder = "/root/rwhois/net2/"; } if ($row['baseaddr'] > ip2long("220.0.0.0") and $row['baseaddr'] < ip2long("220.0.7.255")) {//net3 $netFolder = "/root/rwhois/net3/"; } if ($row['baseaddr'] > ip2long("230.0.0.0") and $row['baseaddr'] < ip2long("230.0.7.255")) {//net4 $netFolder = "/root/rwhois/net4/"; } if ($row['baseaddr'] > ip2long("240.0.0.0") and $row['baseaddr'] < ip2long("240.0.15.255")) {//net5 $netFolder = "/root/rwhois/net5/"; } //find subnet size if ($row['subnetsize'] == 8) { $subnet = "29"; } if ($row['subnetsize'] == 16) { $subnet = "28"; } if ($row['subnetsize'] == 32) { $subnet = "27"; } if ($row['subnetsize'] == 64) { $subnet = "26"; } if ($row['subnetsize'] == 128) { $subnet = "25"; } if ($row['subnetsize'] == 256) { $subnet = "24"; } if ($row['subnetsize'] == 512) { $subnet = "23"; } if ($row['subnetsize'] == 1024) { $subnet = "22"; } if ($row['subnetsize'] == 2048) { $subnet = "21"; } if ($row['subnetsize'] == 4096) { $subnet = "20"; } //this is the formatting for the files $ipAddr = long2ip($row['baseaddr']); $ipAddrEnd = long2ip($row['baseaddr'] + $row['subnetsize'] - 1); $fp = fopen($netFolder . $ipAddr . "-" . $subnet . ".txt", 'w'); //change the ID to equal what you want fwrite($fp, 'ID: NETBLK-GregSowell-' . $ipAddr . '/' . $subnet . "\n"); fwrite($fp, 'Auth-Area: ' . $ipAddr . '-' . $subnet . "\n"); fwrite($fp, 'Network-Name: ' . $row['descrip'] . "\n"); fwrite($fp, 'IP-Network: ' . $ipAddr . '/' . $subnet . "\n"); fwrite($fp, 'IP-Network-Block: ' . $ipAddr . " - " . $ipAddrEnd . "\n"); //change the org info to yours fwrite($fp, 'Organization: GregSowell.com' . "\n"); //change the contact info to yours fwrite($fp, 'Tech-Contact: [email protected]' . "\n"); //change this to your admin contact fwrite($fp, 'Admin-Contact: DNSADGregSowell-ARIN' . "\n"); fclose($fp); } } mysql_close($conn); //folders and files created, now let's send them to the server $ftp_server = "1.1.1.1"; $ftp_user_name = "user"; $ftp_user_pass = "password"; // set up basic connection $conn_id = ftp_connect($ftp_server) or die("Couldn't connect to $ftp_server"); // login with username and password $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass); echo $login_result . "\n"; ftp_pasv($conn_id, true); //set local dir where config files are sitting $dir = "/root/rwhois/net1/"; //set remote directory where files will be placed //this will be the name of the subnet $remoteDir = "/usr/local/rwhoisd/net-200.0.0.0-21/data/network/"; //ftp_chdir($conn_id, $remoteDir); if (ftp_chdir($conn_id, $remoteDir)) { echo "Current directory is now: " . ftp_pwd($conn_id) . "\n"; } else { echo "Couldn't change directory\n"; } if (is_dir($dir)) { //place our supernet file in. This will be located in our local rwhois directory and will never change. You will have to create //one of these for each of your zones. ftp_put($conn_id, "200.0.0.0.txt", "/root/rwhois/200.0.0.0-21.txt", FTP_BINARY); if ($dh = opendir($dir)) { //loop through the base dir and upload the files while (($file = readdir($dh)) !== false) { $fileSend = $dir . $file; $remote_file = $file; // upload a file if (ftp_put($conn_id, $remote_file, $fileSend, FTP_BINARY)) { //echo "successfully uploaded $file\n"; } else { echo "There was a problem while uploading $file\n"; } //delete the file we just sent unlink($fileSend); } closedir($dh); } } //now we move to the next dir $dir = "/root/rwhois/net2/"; $remoteDir = "/usr/local/rwhoisd/net-210.0.0.0-20/data/network/"; if (ftp_chdir($conn_id, $remoteDir)) { echo "Current directory is now: " . ftp_pwd($conn_id) . "\n"; } else { echo "Couldn't change directory\n"; } if (is_dir($dir)) { ftp_put($conn_id, "210.0.0.0-20.txt", "/root/rwhois/210.0.0.0-20.txt", FTP_BINARY); if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { //echo $file; $fileSend = $dir . $file; $remote_file = $file; // upload a file if (ftp_put($conn_id, $remote_file, $fileSend, FTP_BINARY)) { //echo "successfully uploaded $file\n"; } else { echo "There was a problem while uploading $file\n"; } unlink($fileSend); } closedir($dh); } } $dir = "/root/rwhois/net3/"; $remoteDir = "/usr/local/rwhoisd/net-220.0.0.0-21/data/network/"; //ftp_chdir($conn_id, $remoteDir); if (ftp_chdir($conn_id, $remoteDir)) { echo "Current directory is now: " . ftp_pwd($conn_id) . "\n"; } else { echo "Couldn't change directory\n"; } if (is_dir($dir)) { ftp_put($conn_id, "220.0.0.0-21.txt", "/root/rwhois/220.0.0.0-21.txt", FTP_BINARY); if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { //echo $file; $fileSend = $dir . $file; $remote_file = $file; // upload a file if (ftp_put($conn_id, $remote_file, $fileSend, FTP_BINARY)) { //echo "successfully uploaded $file\n"; } else { echo "There was a problem while uploading $file\n"; } unlink($fileSend); } closedir($dh); } } $dir = "/root/rwhois/net4/"; $remoteDir = "/usr/local/rwhoisd/net-230.0.0.0-21/data/network/"; if (ftp_chdir($conn_id, $remoteDir)) { echo "Current directory is now: " . ftp_pwd($conn_id) . "\n"; } else { echo "Couldn't change directory\n"; } if (is_dir($dir)) { ftp_put($conn_id, "230.0.0.0-21.txt", "/root/rwhois/230.0.0.0-21.txt", FTP_BINARY); if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { $fileSend = $dir . $file; $remote_file = $file; // upload a file if (ftp_put($conn_id, $remote_file, $fileSend, FTP_BINARY)) { //echo "successfully uploaded $file\n"; } else { echo "There was a problem while uploading $file\n"; } unlink($fileSend); } closedir($dh); } } $dir = "/root/rwhois/net5/"; $remoteDir = "/usr/local/rwhoisd/net-240.0.0.0-20/data/network/"; if (ftp_chdir($conn_id, $remoteDir)) { echo "Current directory is now: " . ftp_pwd($conn_id) . "\n"; } else { echo "Couldn't change directory\n"; } if (is_dir($dir)) { ftp_put($conn_id, "240.0.0.0-20.txt", "/root/rwhois/240.0.0.0-20.txt", FTP_BINARY); if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { $fileSend = $dir . $file; $remote_file = $file; // upload a file if (ftp_put($conn_id, $remote_file, $fileSend, FTP_BINARY)) { //echo "successfully uploaded $file\n"; } else { echo "There was a problem while uploading $file\n"; } unlink($fileSend); } closedir($dh); } } // close the connection ftp_close($conn_id); ?>

RWhois Server

Once you have rwhois configured on this server and an FTP server, you can begin adding these scripts.

The rwhoisCleanFolder.sh script is meant to run first. It should run around an hour before you ftp job runs. This guy deletes the files out of your rwhois folders.

1
2
3
4
5
6
7
8
#!/bin/sh
#######rwhoisCleanFolder.sh######
 
rm -f /usr/local/rwhoisd/net-200.0.0.0-21/data/network/*.txt
rm -f /usr/local/rwhoisd/net-210.0.0.0.0-20/data/network/*.txt
rm -f /usr/local/rwhoisd/net-220.0.0.0-21/data/network/*.txt
rm -f /usr/local/rwhoisd/net-230.0.0.0-21/data/network/*.txt
rm -f /usr/local/rwhoisd/net-240.0.0.0-20/data/network/*.txt

The rwhoisIndex.sh script should be scheduled to run 15 mins or so after your files are on the server. This indexes all of your config files. It then stops and starts the rwhois server. Once this script runs, your are done!

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/sh
#####rwhoisIndex.sh#####
 
#index all ip zones
/usr/local/rwhoisd/bin/rwhois_indexer -c /usr/local/rwhoisd/rwhoisd.conf -i -v -A 200.0.0.0/21 -C network -s txt
/usr/local/rwhoisd/bin/rwhois_indexer -c /usr/local/rwhoisd/rwhoisd.conf -i -v -A 210.0.0.0/20 -C network -s txt
/usr/local/rwhoisd/bin/rwhois_indexer -c /usr/local/rwhoisd/rwhoisd.conf -i -v -A 220.0.0.0/21 -C network -s txt
/usr/local/rwhoisd/bin/rwhois_indexer -c /usr/local/rwhoisd/rwhoisd.conf -i -v -A 230.0.0.0/21 -C network -s txt
/usr/local/rwhoisd/bin/rwhois_indexer -c /usr/local/rwhoisd/rwhoisd.conf -i -v -A 240.0.0.0/20 -C network -s txt
 
#restart the rwhoisd service
/etc/init.d/rwhoisd stop
/etc/init.d/rwhoisd start

9 Comments

leave a comment
  1. Jimmy / Mar 9 2009

    This part of the code

    //find subnet size
    if ($row['subnetsize'] == 8) {
    $subnet = "29";
    }
    if ($row['subnetsize'] == 16) {
    $subnet = "28";
    }
    if ($row['subnetsize'] == 32) {
    $subnet = "27";
    }
    if ($row['subnetsize'] == 64) {
    $subnet = "26";
    }
    if ($row['subnetsize'] == 128) {
    $subnet = "25";
    }
    if ($row['subnetsize'] == 256) {
    $subnet = "24";
    }
    if ($row['subnetsize'] == 512) {
    $subnet = "23";
    }
    if ($row['subnetsize'] == 1024) {
    $subnet = "22";
    }
    if ($row['subnetsize'] == 2048) {
    $subnet = "21";
    }
    if ($row['subnetsize'] == 4096) {
    $subnet = "20";
    }

    could be changed to


    $subnets = array(8 => 29, 16 => 28, 32 => 27, 64 => 26, 128 => 25, 256 => 24, 512 => 23, 1024 => 22, 2048 => 21, 4096 => 20);
    $subnet = $subnets[$row['subnetsize']];

  2. Jimmy / Mar 9 2009

    Or better yet, you could drop it to 1 line with
    $subnet = 32 - log($row['subnetsize'], 2);

  3. Greg / Mar 9 2009

    Jimmy,

    Thanks for the snippet. This really would consolidate the code down…if I wasn’t so lazy, I would probably update the script to use it…hehehe. Just kidding, when I update, I’ll add, thanks.

    Greg

  4. Frank / Mar 23 2011

    2 years later, and still highly valuable! Thank you for the script!
    I found an issue with:

    1
    
    if ($row['baseaddr'] &gt; ip2long("200.0.0.0") and $row['baseaddr'] = 0) and (gmp_cmp(ip2long($my_ip), ip2long("200.0.7.255")) ="

    so as not to accidentally skip the ‘first possible’ subnet.

    Thanks a ton for the code!

  5. Greg / Mar 23 2011

    @Frank
    Thanks for the update! I’m glad to see someone other than myself has braved this…hehe.

    You also have a lengthy resume. I’ve never worked anywhere for 10 years…I believe I might go mad.

  6. kris / Sep 18 2011

    So you are running ipplan and rwhoisd on the same server for this?

  7. Greg / Sep 18 2011

    @Kris
    These run on two different servers. It would be a lot simpler if it were the same server 🙂 We keep internal and external resources separate.

  8. Kris / Jul 9 2013

    Are there any updates to this for newer PHP versions?

  9. Greg / Jul 9 2013

    @Kris
    Sorry, I’ve not touched this in ages.

Leave a Comment

 

*