/**
* Wrapper for inet_pton()
*
* Converts a human readable IP address to its packed in_addr representation
* inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
*
* @param string $address	A human readable IPv4 or IPv6 address.
*
* @return mixed		false if address is invalid,
*					in_addr representation of the given address otherwise (string)
*/
function phpbb_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;
}
Example #2
0
 /**
  * @dataProvider data_provider
  */
 public function test_inet_pton($address, $hex)
 {
     $this->assertEquals($hex, bin2hex(phpbb_inet_pton($address)));
 }