/**
* Wrapper for inet_ntop()
*
* Converts a packed internet address to a human readable representation
* inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
*
* @param string $in_addr	A 32bit IPv4, or 128bit IPv6 address.
*
* @return mixed		false on failure,
*					string otherwise
*/
function phpbb_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;
    }
}
Example #2
0
 /**
  * @dataProvider data_provider
  */
 public function test_inet_ntop($address, $hex)
 {
     $this->assertEquals($address, phpbb_inet_ntop(pack('H*', $hex)));
 }