[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/simplepie/library/SimplePie/Net/ -> IPv6.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1