DATA['IP'] = $ip; # Die Maske ist als Maskenlänge 0..30 angegeben preg_match("/^\d+$/", $ma, $matches ); if( $matches ){ $masklen = $matches[0]; if( $masklen > 32 ){ throw new Exception("Maskenlänge ungültig!"); } if( $masklen == 31 ){ throw new Exception("Maskenlänge ungültig!"); } $masknum = $this->masklenton($masklen); $this->DATA['MASKLEN'] = $masklen; } else{ $class = __CLASS__; $t = new $class($ma,0); # Maske als IP-Addr $t->bitcmp( new $class('255.255.255.255',0) ); $tlen = min( $t->BITCMP ); # Mit $tlen zurückrechnen auf Dezimalschreibweise der Maske if( $ma != $t->inetntoa($t->masklenton($tlen)) ){ throw new Exception("Netzmaske ungültig!"); } $masklen = $tlen; $masknum = $this->masklenton($masklen); $this->DATA['MASKLEN'] = $masklen; } # Die übergebene IP-Adresse auf Gültigkeit prüfen $ipnum = $this->inetaton($ip); $decim = $this->inetntoa($ipnum); if( $decim != $ip ){ throw new Exception("IPv4-Adresse '$ip' ungültig!"); } # Netzadresse und Broadcastadresse $this->DATA['NETADDR'] = $this->inetntoa($ipnum & $masknum); $this->DATA['BCADDR'] = $this->inetntoa($ipnum |~ $masknum); # Numerische longint fixierten $this->ipnum = $ipnum; $this->masknum = $masknum; # PHP rechnet intern mit Vorzeichen # von daher werden der Lesbarkeit wegen # die Numerischen Werten vorzeichenlos abgelegt $this->DATA['MASKNUM'] = sprintf("%u",$masknum); $this->DATA['IPNUM'] = sprintf("%u", $ipnum); $this->DATA['NETMASK'] = $this->inetntoa( $masknum ); # Anzahl möglicher Hosts berechnen $this->DATA['HOSTS'] = $this->DATA['MASKLEN'] == 32 ? 'Single Host' : sprintf("%u", $this->inetaton($this->DATA['BCADDR']) - $this->inetaton($this->DATA['NETADDR']) - 1 ); # Erster und letzter Host im Subnetz $this->DATA['FIRST'] = $this->addx($this->DATA['NETADDR'], 1); $this->DATA['LAST'] = $this->addx($this->DATA['BCADDR'], -1); } function data(){ return $this->DATA; } function addx($addr, $x){ $num = $this->inetaton($addr) + $x; return $this->inetntoa($num); } # Dezimal zu Numerisch function inetaton($ipa){ $octs = explode(".", $ipa); if( count($octs) != 4 ){ throw new Exception("Syntax für Adresse '$ipa' ungültig!"); } $bin = pack("CCCC", $octs[0], $octs[1], $octs[2], $octs[3]); $num = unpack("N", $bin); return $num[1]; } # Numerisch zu Dezimal function inetntoa($num){ $bin = pack("N", $num); $a = unpack("C4", $bin); return join(".", $a); } function masklenton($masklen){ if($masklen == 0){ return 0; } else{ return(0xffffFFFF <<(32 - $masklen)); } } # Bitvergleich von links nach rechts # Route Summary function bitcmp($ipo){ $bitcmp = 0; foreach( array(31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) as $bit ){ if( ($this->ipnum >> $bit & 1) == ($ipo->ipnum >> $bit & 1) ){ $bitcmp++; } else{ break; } } $this->BITCMP[ $ipo->DATA['IP'] ] = $bitcmp ; } } ########################################################################### #try{ # $ipo = new IPv4('10.0.0.0', '255.240.0.0'); # $ip = new IPv4('127.0.0.0', 8); # print_r( $ip ); #} #catch(Exception $e){ # die( $e->getMessage() ); #}