You are here

public static function Helper::ip__mask_match in Anti Spam by CleanTalk 9.1.x

Same name and namespace in other branches
  1. 8.4 src/lib/Cleantalk/Common/Helper.php \Cleantalk\Common\Helper::ip__mask_match()

* Check if the IP belong to mask. Recursive. * Octet by octet for IPv4 * Hextet by hextet for IPv6 * *

Parameters

string $ip: * @param string $cidr work to compare with * @param string $ip_type IPv6 or IPv4 * @param int $xtet_count Recursive counter. Determs current part of address to check. * * @return bool

2 calls to Helper::ip__mask_match()
Helper::ip__get in src/lib/Cleantalk/Common/Helper.php
Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip)
Helper::ip__is_private_network in src/lib/Cleantalk/Common/Helper.php
* Checks if the IP is in private range * *

File

src/lib/Cleantalk/Common/Helper.php, line 298

Class

Helper
CleanTalk Helper class. Compatible with any CMS.

Namespace

Cleantalk\Common

Code

public static function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = 0) {
  if (is_array($cidr)) {
    foreach ($cidr as $curr_mask) {
      if (self::ip__mask_match($ip, $curr_mask, $ip_type)) {
        return true;
      }
    }
    unset($curr_mask);
    return false;
  }
  if (!self::ip__validate($ip) || !self::cidr__validate($cidr)) {
    return false;
  }
  $xtet_base = $ip_type == 'v4' ? 8 : 16;

  // Calculate mask
  $exploded = explode('/', $cidr);
  $net_ip = $exploded[0];
  $mask = $exploded[1];

  // Exit condition
  $xtet_end = ceil($mask / $xtet_base);
  if ($xtet_count == $xtet_end) {
    return true;
  }

  // Lenght of bits for comparsion
  $mask = $mask - $xtet_base * $xtet_count >= $xtet_base ? $xtet_base : $mask - $xtet_base * $xtet_count;

  // Explode by octets/hextets from IP and Net
  $net_ip_xtets = explode($ip_type == 'v4' ? '.' : ':', $net_ip);
  $ip_xtets = explode($ip_type == 'v4' ? '.' : ':', $ip);

  // Standartizing. Getting current octets/hextets. Adding leading zeros.
  $net_xtet = str_pad(decbin($ip_type == 'v4' ? $net_ip_xtets[$xtet_count] : @hexdec($net_ip_xtets[$xtet_count])), $xtet_base, 0, STR_PAD_LEFT);
  $ip_xtet = str_pad(decbin($ip_type == 'v4' ? $ip_xtets[$xtet_count] : @hexdec($ip_xtets[$xtet_count])), $xtet_base, 0, STR_PAD_LEFT);

  // Comparing bit by bit
  for ($i = 0, $result = true; $mask != 0; $mask--, $i++) {
    if ($ip_xtet[$i] != $net_xtet[$i]) {
      $result = false;
      break;
    }
  }

  // Recursing. Moving to next octet/hextet.
  if ($result) {
    $result = self::ip__mask_match($ip, $cidr, $ip_type, $xtet_count + 1);
  }
  return $result;
}