1<?php 2/** 3 * IPv4.php 4 * 5 * -Description- 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <https://www.gnu.org/licenses/>. 19 * 20 * @link https://www.librenms.org 21 * @copyright 2017 Tony Murray 22 * @author Tony Murray <murraytony@gmail.com> 23 */ 24 25namespace LibreNMS\Util; 26 27use LibreNMS\Exceptions\InvalidIpException; 28 29class IPv4 extends IP 30{ 31 /** 32 * IPv4 constructor. 33 * @param string $ipv4 34 * @throws InvalidIpException 35 */ 36 public function __construct($ipv4) 37 { 38 $this->host_bits = 32; 39 [$this->ip, $this->cidr] = $this->extractCidr($ipv4); 40 41 if (! self::isValid($this->ip)) { 42 throw new InvalidIpException("$ipv4 is not a valid ipv4 address"); 43 } 44 } 45 46 /** 47 * Check if the supplied IP is valid. 48 * @param string $ipv4 49 * @param bool $exclude_reserved Exclude reserved IP ranges. 50 * @return bool 51 */ 52 public static function isValid($ipv4, $exclude_reserved = false) 53 { 54 $filter = FILTER_FLAG_IPV4; 55 if ($exclude_reserved) { 56 $filter |= FILTER_FLAG_NO_RES_RANGE; 57 } 58 59 return filter_var($ipv4, FILTER_VALIDATE_IP, $filter) !== false; 60 } 61 62 /** 63 * Convert an IPv4 network mask to a bit mask. For example: 255.255.255.0 -> 24 64 * @param string $netmask 65 * @return int 66 */ 67 public static function netmask2cidr($netmask) 68 { 69 $long = ip2long($netmask); 70 $base = ip2long('255.255.255.255'); 71 72 return (int) (32 - log(($long ^ $base) + 1, 2)); 73 } 74 75 /** 76 * Returns the netmask of this IP address. For example: 255.255.255.0 77 * @return string 78 */ 79 public function getNetmask() 80 { 81 return long2ip($this->cidr2long($this->cidr)); 82 } 83 84 /** 85 * Convert an IPv4 bit mask to a long. Generally used with long2ip() or bitwise operations. 86 * @return int 87 */ 88 private function cidr2long($cidr) 89 { 90 return -1 << (32 - (int) $cidr); 91 } 92 93 /** 94 * Check if this IP address is contained inside the network. 95 * @param string $network should be in cidr format. 96 * @return mixed 97 */ 98 public function inNetwork($network) 99 { 100 [$net, $cidr] = $this->extractCidr($network); 101 if (! self::isValid($net)) { 102 return false; 103 } 104 105 $mask = $this->cidr2long($cidr); 106 107 return (ip2long($this->ip) & $mask) == (ip2long($net) & $mask); 108 } 109 110 /** 111 * Get the network address of this IP 112 * @param int $cidr if not given will use the cidr stored with this IP 113 * @return string 114 */ 115 public function getNetworkAddress($cidr = null) 116 { 117 if (is_null($cidr)) { 118 $cidr = $this->cidr; 119 } 120 121 return long2ip(ip2long($this->ip) & $this->cidr2long($cidr)); 122 } 123 124 /** 125 * Convert this IP to an snmp index hex encoded 126 * 127 * @return string 128 */ 129 public function toSnmpIndex() 130 { 131 return (string) $this->ip; 132 } 133} 134