annotate vendor/symfony/http-foundation/IpUtils.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\HttpFoundation;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Http utility functions.
Chris@0 16 *
Chris@0 17 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 18 */
Chris@0 19 class IpUtils
Chris@0 20 {
Chris@0 21 /**
Chris@0 22 * This class should not be instantiated.
Chris@0 23 */
Chris@0 24 private function __construct()
Chris@0 25 {
Chris@0 26 }
Chris@0 27
Chris@0 28 /**
Chris@0 29 * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
Chris@0 30 *
Chris@0 31 * @param string $requestIp IP to check
Chris@0 32 * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
Chris@0 33 *
Chris@0 34 * @return bool Whether the IP is valid
Chris@0 35 */
Chris@0 36 public static function checkIp($requestIp, $ips)
Chris@0 37 {
Chris@0 38 if (!is_array($ips)) {
Chris@0 39 $ips = array($ips);
Chris@0 40 }
Chris@0 41
Chris@0 42 $method = substr_count($requestIp, ':') > 1 ? 'checkIp6' : 'checkIp4';
Chris@0 43
Chris@0 44 foreach ($ips as $ip) {
Chris@0 45 if (self::$method($requestIp, $ip)) {
Chris@0 46 return true;
Chris@0 47 }
Chris@0 48 }
Chris@0 49
Chris@0 50 return false;
Chris@0 51 }
Chris@0 52
Chris@0 53 /**
Chris@0 54 * Compares two IPv4 addresses.
Chris@0 55 * In case a subnet is given, it checks if it contains the request IP.
Chris@0 56 *
Chris@0 57 * @param string $requestIp IPv4 address to check
Chris@0 58 * @param string $ip IPv4 address or subnet in CIDR notation
Chris@0 59 *
Chris@0 60 * @return bool Whether the request IP matches the IP, or whether the request IP is within the CIDR subnet
Chris@0 61 */
Chris@0 62 public static function checkIp4($requestIp, $ip)
Chris@0 63 {
Chris@0 64 if (!filter_var($requestIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
Chris@0 65 return false;
Chris@0 66 }
Chris@0 67
Chris@0 68 if (false !== strpos($ip, '/')) {
Chris@0 69 list($address, $netmask) = explode('/', $ip, 2);
Chris@0 70
Chris@0 71 if ($netmask === '0') {
Chris@0 72 return filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
Chris@0 73 }
Chris@0 74
Chris@0 75 if ($netmask < 0 || $netmask > 32) {
Chris@0 76 return false;
Chris@0 77 }
Chris@0 78 } else {
Chris@0 79 $address = $ip;
Chris@0 80 $netmask = 32;
Chris@0 81 }
Chris@0 82
Chris@0 83 return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
Chris@0 84 }
Chris@0 85
Chris@0 86 /**
Chris@0 87 * Compares two IPv6 addresses.
Chris@0 88 * In case a subnet is given, it checks if it contains the request IP.
Chris@0 89 *
Chris@0 90 * @author David Soria Parra <dsp at php dot net>
Chris@0 91 *
Chris@0 92 * @see https://github.com/dsp/v6tools
Chris@0 93 *
Chris@0 94 * @param string $requestIp IPv6 address to check
Chris@0 95 * @param string $ip IPv6 address or subnet in CIDR notation
Chris@0 96 *
Chris@0 97 * @return bool Whether the IP is valid
Chris@0 98 *
Chris@0 99 * @throws \RuntimeException When IPV6 support is not enabled
Chris@0 100 */
Chris@0 101 public static function checkIp6($requestIp, $ip)
Chris@0 102 {
Chris@0 103 if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) {
Chris@0 104 throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
Chris@0 105 }
Chris@0 106
Chris@0 107 if (false !== strpos($ip, '/')) {
Chris@0 108 list($address, $netmask) = explode('/', $ip, 2);
Chris@0 109
Chris@0 110 if ($netmask < 1 || $netmask > 128) {
Chris@0 111 return false;
Chris@0 112 }
Chris@0 113 } else {
Chris@0 114 $address = $ip;
Chris@0 115 $netmask = 128;
Chris@0 116 }
Chris@0 117
Chris@0 118 $bytesAddr = unpack('n*', @inet_pton($address));
Chris@0 119 $bytesTest = unpack('n*', @inet_pton($requestIp));
Chris@0 120
Chris@0 121 if (!$bytesAddr || !$bytesTest) {
Chris@0 122 return false;
Chris@0 123 }
Chris@0 124
Chris@0 125 for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
Chris@0 126 $left = $netmask - 16 * ($i - 1);
Chris@0 127 $left = ($left <= 16) ? $left : 16;
Chris@0 128 $mask = ~(0xffff >> $left) & 0xffff;
Chris@0 129 if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
Chris@0 130 return false;
Chris@0 131 }
Chris@0 132 }
Chris@0 133
Chris@0 134 return true;
Chris@0 135 }
Chris@0 136 }