Address = 0; $this->Prefix = 0; } function GetNetMask(): int { return ((1 << IPV4_BIT_WIDTH) - 1) ^ ((1 << (IPV4_BIT_WIDTH - $this->Prefix)) - 1); } function AddressToString(): string { return implode('.', array(($this->Address >> 24) & 255, ($this->Address >> 16) & 255, ($this->Address >> 8) & 255, ($this->Address & 255))); } function AddressFromString(string $Value): void { $Parts = explode('.', $Value); $this->Address = ($Parts[0] << 24) | ($Parts[1] << 16) | ($Parts[2] << 8) | $Parts[3]; } function GetRange(): array { $From = new NetworkAddressIPv4(); $From->Address = $this->Address; $From->Prefix = IPV4_BIT_WIDTH; $HostMask = 0xffffffff ^ $this->GetNetMask(); $To = new NetworkAddressIPv4(); $To->Address = $From->Address + $HostMask; $To->Prefix = IPV4_BIT_WIDTH; return array('From' => $From, 'To' => $To); } function ChangePrefix(int $NewPrefix): void { $this->Prefix = $NewPrefix; if ($this->Prefix > IPV4_BIT_WIDTH) $this->Prefix = IPV4_BIT_WIDTH; if ($this->Prefix < 0) $this->Prefix = 0; $this->Address = $this->Address & $this->GetNetMask(); } function Contain(NetworkAddressIPv4 $Address): bool { $UpperNetmask = $this->GetNetMask(); if (($this->Prefix < $Address->Prefix) and (($Address->Address & $UpperNetmask) == ($this->Address & $UpperNetmask))) $Result = true; else $Result = false; return $Result; } } define('IPV6_BIT_WIDTH', 128); class NetworkAddressIPv6 { public string $Address; public int $Prefix; function __construct() { $this->Address = 0; $this->Prefix = 0; } function GetNetMask(): string { return Int128Xor(Int128Sub(Int128Shl(IntToInt128(1), IntToInt128(IPV6_BIT_WIDTH)), IntToInt128(1)), Int128Sub(Int128Shl(IntToInt128(1), IntToInt128(IPV6_BIT_WIDTH - $this->Prefix)), IntToInt128(1))); } function AddressToString(): string { return inet_ntop($this->Address); } function AddressFromString(string $Value) { $this->Address = inet_pton($Value); } function ChangePrefix(int $NewPrefix): void { $this->Prefix = $NewPrefix; if ($this->Prefix > IPV6_BIT_WIDTH) $this->Prefix = IPV6_BIT_WIDTH; if ($this->Prefix < 0) $this->Prefix = 0; $this->Address = Int128And($this->Address, $this->GetNetMask()); } function GetOctets(): array { $Result = array(); $Data = array_reverse(unpack('C*', $this->Address)); foreach ($Data as $Item) { $Result[] = dechex($Item & 15); $Result[] = dechex(($Item >> 4) & 15); } return $Result; } function EncodeMAC(string $MAC): void { $MAC = explode(':', $MAC); $Data = unpack('C*', $this->Address); $Data[9] = hexdec($MAC[0]) ^ 0x02; $Data[10] = hexdec($MAC[1]); $Data[11] = hexdec($MAC[2]); $Data[12] = 0xff; $Data[13] = 0xfe; $Data[14] = hexdec($MAC[3]); $Data[15] = hexdec($MAC[4]); $Data[16] = hexdec($MAC[5]); $this->Address = pack_array('C*', $Data); } function Contain(NetworkAddressIPv6 $Address): bool { $UpperNetmask = $this->GetNetMask(); if (($this->Prefix < $Address->Prefix) and ((Int128Equal(Int128And($Address->Address, $UpperNetmask), Int128And($this->Address, $UpperNetmask))))) $Result = true; else $Result = false; return $Result; } }