Calculate Netmask/Gateway from IP Blocks

2019-04-15 18:07发布

Our Datacenter has given us a JSON dump from all of our machines to import into our own inventory management system. This supplies the IP Blocks such as (192.168.1.1/26) but as I am importing hundreds of blocks, I would like to also calculate the Netmask and Gateway.

I looked over the networking functions on the PHP Doxygen but was not able to find any way to do this. How can I calculate Netmask/Gateway from an IP Block?

3条回答
放我归山
2楼-- · 2019-04-15 18:14

The ip address is logical and'ed with the subnet_mask. The subnet_mask can be used to carve out many net_id. Read here for an example: http://www.garykessler.net/library/subnet_masks.html.

查看更多
Animai°情兽
3楼-- · 2019-04-15 18:28
<?php

/*
I have snipped this script from online and modified to give JSON output
*/

$networkArray = array();

// Define your IP address detail in below line
$my_net_info=rtrim('10.240.1.1/22');


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)){
    $networkArray['error'] = "Invalid Input";
}

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)){
        $networkArray['error'] = "Invalid CIDR value. Try an integer 0 - 32";
    }
    $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?
            $networkArray['error'] = "Invalid Netmask";
        }
    }
    $cdr_nmask=bintocdr($bin_nmask);
}

//Check for valid $dq_host
if(! ereg('^0.',$dq_host)){
    foreach( explode(".",$dq_host) as $octet ){
        if($octet > 255){ 
            $networkArray['error'] = "Invalid IP Address";
        }

    }
}
if(!empty($networkArray['error'])){
    echo json_encode($networkArray);
    exit;
}

$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= "0 " . substr(dotbin($bin_net,$cdr_nmask),1) ;
}elseif (ereg('^10',$bin_net)){
    $class="B";
    $dotbin_net= "10 " . substr(dotbin($bin_net,$cdr_nmask),2) ;
}elseif (ereg('^110',$bin_net)){
    $class="C";
    $dotbin_net= "110 " . substr(dotbin($bin_net,$cdr_nmask),3) ;
}elseif (ereg('^1110',$bin_net)){
    $class="D";
    $dotbin_net= "1110 " . substr(dotbin($bin_net,$cdr_nmask),4) ;
    $special="Multicast Address Space";
}else{
    $class="E";
    $dotbin_net= "1111 " . substr(dotbin($bin_net,$cdr_nmask),4) ;
    $special="Experimental Address Space";
}

if (ereg('^(00001010)|(101011000001)|(1100000010101000)',$bin_net)){
     $special='RFC-1918 Private Internet Address';
}

// Print Results

$networkArray['class'] = $class;
$networkArray['address'] =  $dq_host;
$networkArray['mask'] = bintodq($bin_nmask);
$networkArray['cdr'] = $cdr_nmask;
$networkArray['wildcard'] = bintodq($bin_wmask);
$networkArray['network'] = bintodq($bin_net);
$networkArray['broadcast'] = bintodq($bin_bcast);
$networkArray['hostmin'] = bintodq($bin_first);
$networkArray['hostmax'] = bintodq($bin_last);
$networkArray['hostnet'] = $host_total;
$networkArray['special'] = $special;

$networkArray['bin-address'] =  dotbin($bin_host,$cdr_nmask);
$networkArray['bin-mask'] = dotbin($bin_nmask, $cdr_nmask);
$networkArray['bin-wildcard'] = dotbin($bin_wmask, $cdr_nmask);
$networkArray['bin-network'] = $dotbin_net;
$networkArray['bin-broadcast'] = dotbin($bin_bcast, $cdr_nmask);
$networkArray['bin-hostmin'] = dotbin($bin_first, $cdr_nmask);
$networkArray['bin-hostmax'] = dotbin($bin_last, $cdr_nmask);

echo json_encode($networkArray);

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);
}
?>
查看更多
闹够了就滚
4楼-- · 2019-04-15 18:40

You can calculate the ip and mask using something like this:

$ip_with_mask = '192.168.1.1/26';
list($ip, $mask_int) = explode('/', $ip_with_mask);
$mask_nr = (pow(2, $mask_int) - 1) << (32 - $mask_int); 
//pow(2, $x) - 1 changes the number to a number made of that many set bits 
//and $y << (32 - $x) shifts it to the end of the 32 bits
$mask = long2ip($mask_nr);
$subnet_ip = long2ip(ip2long($ip) & $mask_nr);
$gateway_ip = long2ip((ip2long($ip) & $mask_nr) + 1);
查看更多
登录 后发表回答