diff options
author | Marek A. RuszczyĆski <aptx@phpbb.com> | 2010-07-29 22:24:05 +0200 |
---|---|---|
committer | Andreas Fischer <bantu@phpbb.com> | 2011-01-03 00:09:51 +0100 |
commit | 2aa54bb1560303cc526f13d43b3df0d451acd9f1 (patch) | |
tree | 356bc75823217fa9c8add4ff02957f4befa88414 /phpBB/includes | |
parent | ae43221399d8d73b38d1f76da5b9ea6b7a6fbb5e (diff) | |
download | forums-2aa54bb1560303cc526f13d43b3df0d451acd9f1.tar forums-2aa54bb1560303cc526f13d43b3df0d451acd9f1.tar.gz forums-2aa54bb1560303cc526f13d43b3df0d451acd9f1.tar.bz2 forums-2aa54bb1560303cc526f13d43b3df0d451acd9f1.tar.xz forums-2aa54bb1560303cc526f13d43b3df0d451acd9f1.zip |
[ticket/9746] Added PHP implementation of inet_pton and inet_ntop.
PHPBB3-9746
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/functions.php | 120 |
1 files changed, 118 insertions, 2 deletions
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 0b747058f7..ac3641ae17 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3343,10 +3343,65 @@ function phpbb_ip_normalise($address) * * @return mixed false on failure, * string otherwise +* +* @author APTX */ function phpbb_inet_ntop($in_addr) { - return inet_ntop($in_addr); + $in_addr = bin2hex($in_addr); + + switch (strlen($in_addr)) + { + case 8: + return implode('.', array_map('hexdec', str_split($in_addr, 2))); + + case 32: + if (substr($in_addr, 0, 24) === '00000000000000000000ffff') + { + return phpbb_inet_ntop(pack('H*', substr($in_addr, 24))); + } + + $parts = str_split($in_addr, 4); + $parts = preg_replace('/^0+(?!$)/', '', $parts); + $ret = implode(':', $parts); + + $matches = array(); + preg_match_all('/(?<=:|^)(?::?0){2,}/', $ret, $matches, PREG_OFFSET_CAPTURE); + $matches = $matches[0]; + + if (empty($matches)) + { + return $ret; + } + + $longest_match = ''; + $longest_match_offset = 0; + foreach ($matches as $match) + { + if (strlen($match[0]) > strlen($longest_match)) + { + $longest_match = $match[0]; + $longest_match_offset = $match[1]; + } + } + + $ret = substr_replace($ret, '', $longest_match_offset, strlen($longest_match)); + + if ($longest_match_offset == strlen($ret)) + { + $ret .= ':'; + } + + if ($longest_match_offset == 0) + { + $ret = ':' . $ret; + } + + return $ret; + + default: + return false; + } } /** @@ -3358,10 +3413,71 @@ function phpbb_inet_ntop($in_addr) * @param string $address A human readable IPv4 or IPv6 address. * * @return string in_addr representation of the given address +* +* @author APTX */ function phpbb_inet_pton($address) { - return inet_pton($address); + $ret = ''; + if (preg_match(get_preg_expression('ipv4'), $address)) + { + foreach (explode('.', $address) as $part) + { + $ret .= ($part <= 0xF ? '0' : '') . dechex($part); + } + + return pack('H*', $ret); + } + + if (preg_match(get_preg_expression('ipv6'), $address)) + { + $parts = explode(':', $address); + $missing_parts = 8 - sizeof($parts) + 1; + + if (substr($address, 0, 2) === '::') + { + ++$missing_parts; + } + + if (substr($address, -2) === '::') + { + ++$missing_parts; + } + + $embedded_ipv4 = false; + $last_part = end($parts); + + if (preg_match(get_preg_expression('ipv4'), $last_part)) + { + $parts[sizeof($parts) - 1] = ''; + $last_part = phpbb_inet_pton($last_part); + $embedded_ipv4 = true; + --$missing_parts; + } + + foreach ($parts as $i => $part) + { + if (strlen($part)) + { + $ret .= str_pad($part, 4, '0', STR_PAD_LEFT); + } + else if ($i && $i < sizeof($parts) - 1) + { + $ret .= str_repeat('0000', $missing_parts); + } + } + + $ret = pack('H*', $ret); + + if ($embedded_ipv4) + { + $ret .= $last_part; + } + + return $ret; + } + + return false; } /** |