User:Oblivious/SubnetCalc

From Meta, a Wikimedia project coordination wiki
Jump to navigation Jump to search
Blue Glass Arrow.svg MediaWiki logo.png
This page should be moved to MediaWiki.org.
Please do not move the page by hand. It will be imported by a MediaWiki.org administrator with the full edit history. In the meantime, you may continue to edit the page as normal.

SubnetCalc extension, is a subnet calculator. This extension is mostly based on the calculation functions of this open source subnet calculator.

Syntax[edit]

<subnet align=left|center|right allhosts=1>
INPUT
</subnet>


INPUT should be substituted with any of the following formts

1. IP & CIDR Netmask:  10.0.0.1/22 
2. IP & Netmask:       10.0.0.1 255.255.252.0 
3. IP & Wildcard Mask: 10.0.0.1 0.0.3.255

Example[edit]

<subnet align=left>
202.1.192.0/22
</subnet>

Subnetcalc1.jpg



<subnet allhosts=1 align=left>
202.1.199.176/29
</subnet>

Subnetcalc2.jpg

Extension[edit]

<?php
# SubnetCalc is mostly based on the code of open source PHP Subnet Calculator
# Source of PHP Subnet Calculator can be found at http://sourceforge.net/projects/subntcalc/

# To use this extension, create a file named SubnetCalc.php inside extensions directory
# Paste this code inside the file
# Insert require_once("extensions/SubnetCalc.php") to LocalSettings.php

# [[Wikipedia:User:Oblivious]]
# http://meta.wikimedia.org/wiki/User:Oblivious/SubnetCalc
# January 29, 2006

$wgExtensionFunctions[] = "wfSubnetCalc";

function wfSubnetCalc() {
    global $wgParser;
    $wgParser->setHook( "subnet", "CalculateSubnet" );
}

# The callback function for converting the input text to HTML output
function CalculateSubnet( $input, $argv ) {

   $my_net_info = trim($input);
   $align = $argv['align'];
   $allhosts = $argv['allhosts'];

   ##Validate input
   if (! ereg('^([0-9]{1,3}\.){3}[0-9]{1,3}(( ([0-9]{1,3}\.){3}[0-9]{1,3})|(/[0-9]{1,2}))$',$my_net_info)){
        $error = "<pre><font color=red>Invalid Input.<br> <b>Use</b> IP & CIDR Netmask:  10.0.0.1/22 <br> Or IP & Netmask: 10.0.0.1 255.255.252.0 <br> Or IP & Wildcard Mask: 10.0.0.1 0.0.3.255</font>< /pre>";
        return $error;
   }


   ##Determine the input type
   if (ereg("/",$my_net_info)){  //if cidr type mask
        $dq_host = strtok("$my_net_info", "/");
        $cdr_nmask = strtok("/");
        if (!($cdr_nmask >= 0 && $cdr_nmask <= 32)){
                return("<pre><font color=red>Invalid CIDR value. Try an integer 0 - 32.</font>< /pre>");
        }
        $bin_nmask=cdrtobin($cdr_nmask);
        $bin_wmask=binnmtowm($bin_nmask);
   } else { //Dotted quad mask?
        $dqs=explode(" ", $my_net_info);
        $dq_host=$dqs[0];
        $bin_nmask=dqtobin($dqs[1]);
        $bin_wmask=binnmtowm($bin_nmask);
        if (ereg("0",rtrim($bin_nmask, "0"))) {  //Wildcard mask then? hmm?
                $bin_wmask=dqtobin($dqs[1]);
                $bin_nmask=binwmtonm($bin_wmask);
                if (ereg("0",rtrim($bin_nmask, "0"))){ //If it's not wcard, whussup?
                        return("<pre><font color=red>Invalid Netmask.</font>< /pre>");
                }
        }
        $cdr_nmask=bintocdr($bin_nmask);
   }

   //Check for valid $dq_host
   if(! ereg('^0.',$dq_host)){
        foreach( explode(".",$dq_host) as $octet ){
                if($octet > 255){
                        return("<pre><font color=red>Invalid IP Address</font>< /pre>");
                }

        }
   }

   $bin_host=dqtobin($dq_host);
   $bin_bcast=(str_pad(substr($bin_host,0,$cdr_nmask),32,1));
   $bin_net=(str_pad(substr($bin_host,0,$cdr_nmask),32,0));
   $bin_first=(str_pad(substr($bin_net,0,31),32,1));
   $bin_last=(str_pad(substr($bin_bcast,0,31),32,0));
   $host_total=(bindec(str_pad("",(32-$cdr_nmask),1)) - 1);

   if ($host_total <= 0){  //Takes care of 31 and 32 bit masks.
        $bin_first="N/A" ; $bin_last="N/A" ; $host_total="N/A";
        if ($bin_net === $bin_bcast) $bin_bcast="N/A";
   }

//Determine Class
   if (ereg('^0',$bin_net)){
        $class="A";
        $dotbin_net= "<font color=\"Green\">0</font>" . substr(dotbin($bin_net,$cdr_nmask),1) ;
   }elseif (ereg('^10',$bin_net)){
        $class="B";
        $dotbin_net= "<font color=\"Green\">10</font>" . substr(dotbin($bin_net,$cdr_nmask),2) ;
   }elseif (ereg('^110',$bin_net)){
        $class="C";
        $dotbin_net= "<font color=\"Green\">110</font>" . substr(dotbin($bin_net,$cdr_nmask),3) ;
   }elseif (ereg('^1110',$bin_net)){
        $class="D";
        $dotbin_net= "<font color=\"Green\">1110</font>" . substr(dotbin($bin_net,$cdr_nmask),4) ;
        $special="<font color=\"Green\">Class D = Multicast Address Space.</font>";
   }else{
        $class="E";
        $dotbin_net= "<font color=\"Green\">1111</font>" . substr(dotbin($bin_net,$cdr_nmask),4) ;
        $special="<font color=\"Green\">Class E = Experimental Address Space.</font>";
   }

   if (ereg('^(00001010)|(101011000001)|(1100000010101000)',$bin_net)){
         $special='(<a href="http://www.ietf.org/rfc/rfc1918.txt">RFC-1918 Private Internet Address</a>)';
   }

   $address = $dq_host;
   $addressBin = dotbin($bin_host,$cdr_nmask);
   $netmask = bintodq($bin_nmask);
   $netmaskBin = dotbin($bin_nmask, $cdr_nmask);
   $wildcard = bintodq($bin_wmask);
   $wildcardBin = dotbin($bin_wmask, $cdr_nmask);
   $network = bintodq($bin_net);
   $networkBin = $dotbin_net;
   $networkClass = $class;
   $broadcast = bintodq($bin_bcast);
   $broadcastBin = dotbin($bin_bcast, $cdr_nmask);
   $hostmin = bintodq($bin_first);
   $hostminBin = dotbin($bin_first, $cdr_nmask);
   $hostmax = bintodq($bin_last);
   $hostmaxBin = dotbin($bin_last, $cdr_nmask);
   $hostsNet = $host_total;
   $special = "<br>" . $special; //just for the sake of doing it :)
   $starthost = ip2long($hostmin);

   if($allhosts) {
        $allhosts = generatehosts($host_total, $starthost);
        $allhosts = implode('<br> ' , $allhosts);
   }

   $output = "<table class=\"wikitable\" align=\"$align\">
                <tr>
                <th colspan=\"3\"> <b>Subnet info for $my_net_info</b>
                </th></tr>
                <tr>
                <th> Address
                </th><td> <font color=\"blue\">$address</font> </td><td> <font color=\"brown\">$addressBin</font>
                </td></tr>
                <tr>
                <th>Netmask
                </th><td><font color=\"blue\">$netmask</font></td><td> <font color=\"red\">$netmaskBin</font>
                </td></tr>
                <tr>
                <th>Wildcard
                </th><td><font color=\"blue\">$wildcard</font></td><td> <font color=\"brown\">$wildcardBin</font>
                </td></tr>
                <tr>
                <th>Network
                </th><td><font color=\"blue\">$network</font></td><td> <font color=\"brown\">$networkBin</font>
                </td></tr>
                <tr>
                <th>Broadcast
                </th><td><font color=\"blue\">$broadcast</font></td><td> <font color=\"brown\">$broadcastBin</font>
                </td></tr>
                <tr>
                <th>HostMin
                </th><td><font color=\"blue\">$hostmin</font></td><td><font color=\"brown\">$hostminBin</font>
                </td></tr>
                <tr>
                <th>HostMax
                </th><td><font color=\"blue\">$hostmax</font></td><td><font color=\"brown\">$hostmaxBin</font>
                </td></tr>
                <tr>
                <th>Hosts/Net
                </th><td><font color=\"blue\"><center>$hostsNet</center></font> </td><td><font color=\"green\">Class $networkClass network</font> $special $allhosts
                </td></tr></table>";

    return $output;

}


##Calculation-specific funtions
function binnmtowm($binin){
        $binin=rtrim($binin, "0");
        if (!ereg("0",$binin) ){
                return str_pad(str_replace("1","0",$binin), 32, "1");
        } else return "1010101010101010101010101010101010101010";
}

function bintocdr ($binin){
        return strlen(rtrim($binin,"0"));
}

function bintodq ($binin) {
        if ($binin=="N/A") return $binin;
        $binin=explode(".", chunk_split($binin,8,"."));
        for ($i=0; $i<4 ; $i++) {
                $dq[$i]=bindec($binin[$i]);
        }
        return implode(".",$dq) ;
}

function bintoint ($binin){
        return bindec($binin);
}

function binwmtonm($binin){
        $binin=rtrim($binin, "1");
        if (!ereg("1",$binin)){
                return str_pad(str_replace("0","1",$binin), 32, "0");
        } else return "1010101010101010101010101010101010101010";
}

function cdrtobin ($cdrin){
        return str_pad(str_pad("", $cdrin, "1"), 32, "0");
}

function dotbin($binin,$cdr_nmask){
        // splits 32 bit bin into dotted bin octets
        if ($binin=="N/A") return $binin;
        $oct=rtrim(chunk_split($binin,8,"."),".");
        if ($cdr_nmask > 0){
                $offset=sprintf("%u",$cdr_nmask/8) + $cdr_nmask ;
                return substr($oct,0,$offset ) . "   " . substr($oct,$offset) ;
        } else {
        return $oct;
        }
}

function dqtobin($dqin) {
        $dq = explode(".",$dqin);
        for ($i=0; $i<4 ; $i++) {
           $bin[$i]=str_pad(decbin($dq[$i]), 8, "0", STR_PAD_LEFT);
        }
        return implode("",$bin);
}

function inttobin ($intin) {
        return str_pad(decbin($intin), 32, "0", STR_PAD_LEFT);
}

function generatehosts ($host_total, $starthost) {
       for($i=0;$i<=$host_total-1;$i++)
       {
               $ip_range[]=long2ip($starthost+$i);
       }
       return $ip_range;
}

?>