home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / SimplePie / Net / IPv6.php
Encoding:
PHP Script  |  2012-11-21  |  7.4 KB  |  277 lines

  1. <?php
  2. /**
  3.  * SimplePie
  4.  *
  5.  * A PHP-Based RSS and Atom Feed Framework.
  6.  * Takes the hard work out of managing a complete RSS/Atom solution.
  7.  *
  8.  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without modification, are
  12.  * permitted provided that the following conditions are met:
  13.  *
  14.  *     * Redistributions of source code must retain the above copyright notice, this list of
  15.  *       conditions and the following disclaimer.
  16.  *
  17.  *     * Redistributions in binary form must reproduce the above copyright notice, this list
  18.  *       of conditions and the following disclaimer in the documentation and/or other materials
  19.  *       provided with the distribution.
  20.  *
  21.  *     * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22.  *       to endorse or promote products derived from this software without specific prior
  23.  *       written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26.  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27.  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28.  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32.  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33.  * POSSIBILITY OF SUCH DAMAGE.
  34.  *
  35.  * @package SimplePie
  36.  * @version 1.3.1
  37.  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
  38.  * @author Ryan Parman
  39.  * @author Geoffrey Sneddon
  40.  * @author Ryan McCue
  41.  * @link http://simplepie.org/ SimplePie
  42.  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43.  */
  44.  
  45.  
  46. /**
  47.  * Class to validate and to work with IPv6 addresses.
  48.  *
  49.  * @package SimplePie
  50.  * @subpackage HTTP
  51.  * @copyright 2003-2005 The PHP Group
  52.  * @license http://www.opensource.org/licenses/bsd-license.php
  53.  * @link http://pear.php.net/package/Net_IPv6
  54.  * @author Alexander Merz <alexander.merz@web.de>
  55.  * @author elfrink at introweb dot nl
  56.  * @author Josh Peck <jmp at joshpeck dot org>
  57.  * @author Geoffrey Sneddon <geoffers@gmail.com>
  58.  */
  59. class SimplePie_Net_IPv6
  60. {
  61.     /**
  62.      * Uncompresses an IPv6 address
  63.      *
  64.      * RFC 4291 allows you to compress concecutive zero pieces in an address to
  65.      * '::'. This method expects a valid IPv6 address and expands the '::' to
  66.      * the required number of zero pieces.
  67.      *
  68.      * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
  69.      *           ::1         ->  0:0:0:0:0:0:0:1
  70.      *
  71.      * @author Alexander Merz <alexander.merz@web.de>
  72.      * @author elfrink at introweb dot nl
  73.      * @author Josh Peck <jmp at joshpeck dot org>
  74.      * @copyright 2003-2005 The PHP Group
  75.      * @license http://www.opensource.org/licenses/bsd-license.php
  76.      * @param string $ip An IPv6 address
  77.      * @return string The uncompressed IPv6 address
  78.      */
  79.     public static function uncompress($ip)
  80.     {
  81.         $c1 = -1;
  82.         $c2 = -1;
  83.         if (substr_count($ip, '::') === 1)
  84.         {
  85.             list($ip1, $ip2) = explode('::', $ip);
  86.             if ($ip1 === '')
  87.             {
  88.                 $c1 = -1;
  89.             }
  90.             else
  91.             {
  92.                 $c1 = substr_count($ip1, ':');
  93.             }
  94.             if ($ip2 === '')
  95.             {
  96.                 $c2 = -1;
  97.             }
  98.             else
  99.             {
  100.                 $c2 = substr_count($ip2, ':');
  101.             }
  102.             if (strpos($ip2, '.') !== false)
  103.             {
  104.                 $c2++;
  105.             }
  106.             // ::
  107.             if ($c1 === -1 && $c2 === -1)
  108.             {
  109.                 $ip = '0:0:0:0:0:0:0:0';
  110.             }
  111.             // ::xxx
  112.             else if ($c1 === -1)
  113.             {
  114.                 $fill = str_repeat('0:', 7 - $c2);
  115.                 $ip = str_replace('::', $fill, $ip);
  116.             }
  117.             // xxx::
  118.             else if ($c2 === -1)
  119.             {
  120.                 $fill = str_repeat(':0', 7 - $c1);
  121.                 $ip = str_replace('::', $fill, $ip);
  122.             }
  123.             // xxx::xxx
  124.             else
  125.             {
  126.                 $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
  127.                 $ip = str_replace('::', $fill, $ip);
  128.             }
  129.         }
  130.         return $ip;
  131.     }
  132.  
  133.     /**
  134.      * Compresses an IPv6 address
  135.      *
  136.      * RFC 4291 allows you to compress concecutive zero pieces in an address to
  137.      * '::'. This method expects a valid IPv6 address and compresses consecutive
  138.      * zero pieces to '::'.
  139.      *
  140.      * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
  141.      *           0:0:0:0:0:0:0:1        ->  ::1
  142.      *
  143.      * @see uncompress()
  144.      * @param string $ip An IPv6 address
  145.      * @return string The compressed IPv6 address
  146.      */
  147.     public static function compress($ip)
  148.     {
  149.         // Prepare the IP to be compressed
  150.         $ip = self::uncompress($ip);
  151.         $ip_parts = self::split_v6_v4($ip);
  152.  
  153.         // Replace all leading zeros
  154.         $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
  155.  
  156.         // Find bunches of zeros
  157.         if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
  158.         {
  159.             $max = 0;
  160.             $pos = null;
  161.             foreach ($matches[0] as $match)
  162.             {
  163.                 if (strlen($match[0]) > $max)
  164.                 {
  165.                     $max = strlen($match[0]);
  166.                     $pos = $match[1];
  167.                 }
  168.             }
  169.  
  170.             $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
  171.         }
  172.  
  173.         if ($ip_parts[1] !== '')
  174.         {
  175.             return implode(':', $ip_parts);
  176.         }
  177.         else
  178.         {
  179.             return $ip_parts[0];
  180.         }
  181.     }
  182.  
  183.     /**
  184.      * Splits an IPv6 address into the IPv6 and IPv4 representation parts
  185.      *
  186.      * RFC 4291 allows you to represent the last two parts of an IPv6 address
  187.      * using the standard IPv4 representation
  188.      *
  189.      * Example:  0:0:0:0:0:0:13.1.68.3
  190.      *           0:0:0:0:0:FFFF:129.144.52.38
  191.      *
  192.      * @param string $ip An IPv6 address
  193.      * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
  194.      */
  195.     private static function split_v6_v4($ip)
  196.     {
  197.         if (strpos($ip, '.') !== false)
  198.         {
  199.             $pos = strrpos($ip, ':');
  200.             $ipv6_part = substr($ip, 0, $pos);
  201.             $ipv4_part = substr($ip, $pos + 1);
  202.             return array($ipv6_part, $ipv4_part);
  203.         }
  204.         else
  205.         {
  206.             return array($ip, '');
  207.         }
  208.     }
  209.  
  210.     /**
  211.      * Checks an IPv6 address
  212.      *
  213.      * Checks if the given IP is a valid IPv6 address
  214.      *
  215.      * @param string $ip An IPv6 address
  216.      * @return bool true if $ip is a valid IPv6 address
  217.      */
  218.     public static function check_ipv6($ip)
  219.     {
  220.         $ip = self::uncompress($ip);
  221.         list($ipv6, $ipv4) = self::split_v6_v4($ip);
  222.         $ipv6 = explode(':', $ipv6);
  223.         $ipv4 = explode('.', $ipv4);
  224.         if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
  225.         {
  226.             foreach ($ipv6 as $ipv6_part)
  227.             {
  228.                 // The section can't be empty
  229.                 if ($ipv6_part === '')
  230.                     return false;
  231.  
  232.                 // Nor can it be over four characters
  233.                 if (strlen($ipv6_part) > 4)
  234.                     return false;
  235.  
  236.                 // Remove leading zeros (this is safe because of the above)
  237.                 $ipv6_part = ltrim($ipv6_part, '0');
  238.                 if ($ipv6_part === '')
  239.                     $ipv6_part = '0';
  240.  
  241.                 // Check the value is valid
  242.                 $value = hexdec($ipv6_part);
  243.                 if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
  244.                     return false;
  245.             }
  246.             if (count($ipv4) === 4)
  247.             {
  248.                 foreach ($ipv4 as $ipv4_part)
  249.                 {
  250.                     $value = (int) $ipv4_part;
  251.                     if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
  252.                         return false;
  253.                 }
  254.             }
  255.             return true;
  256.         }
  257.         else
  258.         {
  259.             return false;
  260.         }
  261.     }
  262.  
  263.     /**
  264.      * Checks if the given IP is a valid IPv6 address
  265.      *
  266.      * @codeCoverageIgnore
  267.      * @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
  268.      * @see check_ipv6
  269.      * @param string $ip An IPv6 address
  270.      * @return bool true if $ip is a valid IPv6 address
  271.      */
  272.     public static function checkIPv6($ip)
  273.     {
  274.         return self::check_ipv6($ip);
  275.     }
  276. }
  277.