|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of Crawler Detect - the web crawler detection library. |
|
5
|
|
|
* |
|
6
|
|
|
* (c) Mark Beech <[email protected]> |
|
7
|
|
|
* |
|
8
|
|
|
* This source file is subject to the MIT license that is bundled |
|
9
|
|
|
* with this source code in the file LICENSE. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace Jaybizzle\CrawlerDetect\Detectors; |
|
13
|
|
|
|
|
14
|
|
|
use Jaybizzle\CrawlerDetect\Fixtures\Ips; |
|
15
|
|
|
|
|
16
|
|
|
class IpDetector |
|
17
|
|
|
{ |
|
18
|
|
|
public function __construct($userIp) |
|
19
|
|
|
{ |
|
20
|
|
|
$this->userIp = $userIp; |
|
|
|
|
|
|
21
|
|
|
} |
|
22
|
|
|
|
|
23
|
|
|
public function check() |
|
24
|
|
|
{ |
|
25
|
|
|
$ips = new Ips(); |
|
26
|
|
|
|
|
27
|
|
|
foreach ($ips->getAll() as $ip) { |
|
28
|
|
|
if ($this->ipInRange($this->userIp, $ip) === true) { |
|
29
|
|
|
return true; |
|
30
|
|
|
} |
|
31
|
|
|
} |
|
32
|
|
|
|
|
33
|
|
|
return false; |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
public function ipInRange($ip, $range) |
|
37
|
|
|
{ |
|
38
|
|
|
if (strpos($range, '/') !== false) { |
|
39
|
|
|
// $range is in IP/NETMASK format |
|
40
|
|
|
list($range, $netmask) = explode('/', $range, 2); |
|
41
|
|
|
|
|
42
|
|
|
if (strpos($netmask, '.') !== false) { |
|
43
|
|
|
// $netmask is a 255.255.0.0 format |
|
44
|
|
|
$netmask = str_replace('*', '0', $netmask); |
|
45
|
|
|
$netmask_dec = ip2long($netmask); |
|
46
|
|
|
|
|
47
|
|
|
return ((ip2long($ip) & $netmask_dec) == (ip2long($range) & $netmask_dec)); |
|
48
|
|
|
} else { |
|
49
|
|
|
// $netmask is a CIDR size block |
|
50
|
|
|
// fix the range argument |
|
51
|
|
|
$x = explode('.', $range); |
|
52
|
|
|
|
|
53
|
|
|
while (count($x) < 4) { |
|
54
|
|
|
$x[] = '0'; |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
list($a, $b, $c, $d) = $x; |
|
58
|
|
|
$range = sprintf('%u.%u.%u.%u', empty($a) ? '0' : $a, empty($b) ? '0' : $b, empty($c) ? '0' : $c, empty($d) ? '0' : $d); |
|
59
|
|
|
$range_dec = ip2long($range); |
|
60
|
|
|
$ip_dec = ip2long($ip); |
|
61
|
|
|
|
|
62
|
|
|
// Use math to create create the netmask with 'netmask' 1s and then fill it to 32 with 0s |
|
63
|
|
|
$wildcard_dec = pow(2, (32 - $netmask)) - 1; |
|
64
|
|
|
$netmask_dec = ~$wildcard_dec; |
|
65
|
|
|
|
|
66
|
|
|
return (($ip_dec & $netmask_dec) == ($range_dec & $netmask_dec)); |
|
67
|
|
|
} |
|
68
|
|
|
} else { |
|
69
|
|
|
// range might be 255.255.*.* or 1.2.3.0-1.2.3.255 |
|
|
|
|
|
|
70
|
|
|
if (strpos($range, '*') !== false) { // a.b.*.* format |
|
71
|
|
|
// Just convert to A-B format by setting * to 0 for A and 255 for B |
|
72
|
|
|
$lower = str_replace('*', '0', $range); |
|
73
|
|
|
$upper = str_replace('*', '255', $range); |
|
74
|
|
|
$range = "$lower-$upper"; |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
if (strpos($range, '-') !== false) { // A-B format |
|
78
|
|
|
list($lower, $upper) = explode('-', $range, 2); |
|
79
|
|
|
$lower_dec = (float) sprintf('%u', ip2long($lower)); |
|
80
|
|
|
$upper_dec = (float) sprintf('%u', ip2long($upper)); |
|
81
|
|
|
$ip_dec = (float) sprintf('%u', ip2long($ip)); |
|
82
|
|
|
|
|
83
|
|
|
return (($ip_dec >= $lower_dec) && ($ip_dec <= $upper_dec)); |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
throw new Exception('Range argument is not in 1.2.3.4/24 or 1.2.3.4/255.255.255.0 format'); |
|
87
|
|
|
} |
|
88
|
|
|
} |
|
89
|
|
|
} |
|
90
|
|
|
|
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: