User:Oblivious/SubnetCalc
Appearance
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> |
<subnet allhosts=1 align=left> 202.1.199.176/29 </subnet> |
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; } ?>