aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
authorMarek A. RuszczyƄski <aptx@phpbb.com>2010-07-29 22:24:05 +0200
committerAndreas Fischer <bantu@phpbb.com>2011-01-03 00:09:51 +0100
commit2aa54bb1560303cc526f13d43b3df0d451acd9f1 (patch)
tree356bc75823217fa9c8add4ff02957f4befa88414 /phpBB/includes
parentae43221399d8d73b38d1f76da5b9ea6b7a6fbb5e (diff)
downloadforums-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.php120
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;
}
/**