73 lines
2.2 KiB
PHP
73 lines
2.2 KiB
PHP
<?php
|
|
|
|
function binary_mask(int $cidr_mask) {
|
|
return bindec(str_pad(str_repeat('1', $cidr_mask), 32, '0'));
|
|
}
|
|
|
|
function cidr_mask(int $binary_mask) {
|
|
return substr_count(decbin($binary_mask), '1');
|
|
}
|
|
|
|
|
|
Class Network {
|
|
public int $address;
|
|
public int $mask;
|
|
public string $name = "";
|
|
|
|
public function __construct(int $address, int $cidr_mask, string $name = "", string $description = "") {
|
|
$this->mask = binary_mask($cidr_mask);
|
|
$this->address = $address & $this->mask;
|
|
$this->name = $name;
|
|
}
|
|
|
|
public function __toString(): string {
|
|
return long2ip($this->address) . " / " . cidr_mask($this->mask);
|
|
}
|
|
|
|
public function __debugInfo(): array {
|
|
return [
|
|
"name" => $this->name,
|
|
"ip_adress" => long2ip($this->address),
|
|
"cidr_mask" => cidr_mask($this->mask),
|
|
];
|
|
}
|
|
|
|
public function contains(Network $other) {
|
|
return ($other->address & $this->mask) == $this->address;
|
|
}
|
|
}
|
|
|
|
$networks = [
|
|
new Network(ip2long("10.75.0.0"), 16, "Paris"),
|
|
new Network(ip2long("10.94.0.0"), 16, "Val-de-Marne"),
|
|
new Network(ip2long("10.232.0.0"), 16, "DiRIF"),
|
|
new Network(ip2long("10.75.128.0"), 22, "Miollis"),
|
|
new Network(ip2long("10.75.128.0"), 24, "Serveurs"),
|
|
new Network(ip2long("10.75.129.0"), 24, "Data"),
|
|
new Network(ip2long("10.75.8.0"), 22, "Crillon"),
|
|
new Network(ip2long("10.94.8.0"), 22, "Créteil Archives"),
|
|
new Network(ip2long("10.232.160.0"), 22, "Créteil l'Echat"),
|
|
];
|
|
|
|
$subnetworks = [];
|
|
foreach ($networks as $network) {
|
|
$subnetworks[] = ["network" => $network, "subnetworks" => []];
|
|
}
|
|
|
|
usort($subnetworks, function($a, $b) {
|
|
return $b["network"]->mask <=> $a["network"]->mask;
|
|
});
|
|
|
|
$networks_tree = [];
|
|
|
|
while (count($subnetworks)) {
|
|
["network" => $network1, "subnetworks" => $subnetworks1] = array_shift($subnetworks);
|
|
foreach($subnetworks as ["network" => $network2, "subnetworks" => &$subnetworks2]) {
|
|
if ($network2->contains($network1)) {
|
|
$subnetworks2[] = ["network" => $network1, "subnetworks" => $subnetworks1];
|
|
continue 2;
|
|
}
|
|
}
|
|
$networks_tree[] = ["network" => $network1, "subnetworks" => $subnetworks1];
|
|
}
|
|
var_dump($networks_tree); |