1<?php 2declare(strict_types = 1); 3namespace TYPO3\CMS\Core\Utility; 4 5/* 6 * This file is part of the TYPO3 CMS project. 7 * 8 * It is free software; you can redistribute it and/or modify it under 9 * the terms of the GNU General Public License, either version 2 10 * of the License, or any later version. 11 * 12 * For the full copyright and license information, please read the 13 * LICENSE.txt file that was distributed with this source code. 14 * 15 * The TYPO3 project - inspiring people to share! 16 */ 17 18/** 19 * Anonymize a given IP 20 * 21 * Inspired by https://github.com/geertw/php-ip-anonymizer 22 */ 23class IpAnonymizationUtility 24{ 25 26 /** 27 * IPv4 netmask used to anonymize IPv4 address. 28 * 29 * 1) Mask host 30 * 2) Mask host and subnet 31 * 32 * @var array 33 */ 34 const MASKV4 = [ 35 1 => '255.255.255.0', 36 2 => '255.255.0.0' 37 ]; 38 39 /** 40 * IPv6 netmask used to anonymize IPv6 address. 41 * 42 * 1) Mask Interface ID 43 * 2) Mask Interface ID and SLA ID 44 * 45 * @var array 46 */ 47 const MASKV6 = [ 48 1 => 'ffff:ffff:ffff:ffff:0000:0000:0000:0000', 49 2 => 'ffff:ffff:ffff:0000:0000:0000:0000:0000', 50 ]; 51 52 /** 53 * Anonymize given IP 54 * 55 * @param string $address IP address 56 * @param int $mask Allowed values are 0 (masking disabled), 1 (mask host), 2 (mask host and subnet) 57 * @return string 58 * @throws \UnexpectedValueException 59 */ 60 public static function anonymizeIp(string $address, int $mask = null): string 61 { 62 if ($mask === null) { 63 $mask = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['ipAnonymization']; 64 } 65 if ($mask < 0 || $mask > 2) { 66 throw new \UnexpectedValueException(sprintf('The provided value "%d" is not an allowed value for the IP mask.', $mask), 1519739203); 67 } 68 if ($mask === 0) { 69 return $address; 70 } 71 if (empty($address)) { 72 return ''; 73 } 74 75 $packedAddress = @inet_pton($address); 76 if ($packedAddress === false) { 77 return ''; 78 } 79 $length = strlen($packedAddress); 80 81 if ($length === 4) { 82 $bitMask = self::MASKV4[$mask]; 83 } elseif ($length === 16) { 84 $bitMask = self::MASKV6[$mask]; 85 } else { 86 return ''; 87 } 88 return inet_ntop($packedAddress & inet_pton($bitMask)); 89 } 90} 91