PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.2.0
Defender Security – Malware Scanner, Login Security & Firewall v6.2.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / extra / class-ip-helper.php

class-ip-helper.php in Defender Security – Malware Scanner, Login Security & Firewall 6.2.0, at src/extra/class-ip-helper.php

217 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender\Extra;
4 /*
5 * ip_in_range.php - Function to determine if an IP is located in a
6 * specific range as specified via several alternative
7 * formats.
8 *
9 * Network ranges can be specified as:
10 * 1. Wildcard format: 1.2.3.*
11 * 2. CIDR format: 1.2.3/24 OR 1.2.3.4/255.255.255.0
12 * 3. Start-End IP format: 1.2.3.0-1.2.3.255
13 *
14 * Return value BOOLEAN : ip_in_range($ip, $range);
15 *
16 * Copyright 2008: Paul Gregg <[email protected]>
17 * 10 January 2008
18 * Version: 1.2
19 *
20 * Source website: http://www.pgregg.com/projects/php/ip_in_range/
21 * Version 1.2
22 *
23 * This software is Donationware - if you feel you have benefited from
24 * the use of this tool then please consider a donation. The value of
25 * which is entirely left up to your discretion.
26 * http://www.pgregg.com/donate/
27 *
28 * Please do not remove this header, or source attibution from this file.
29 */
30
31 /*
32 * Modified by James Greene <[email protected]> to include IPV6 support
33 * (original version only supported IPV4).
34 * 21 May 2012
35 */
36
37 class IP_Helper {
38 // decbin32
39 // In order to simplify working with IP addresses (in binary) and their
40 // netmasks, it is easier to ensure that the binary strings are padded
41 // with zeros out to 32 characters - IP addresses are 32 bit numbers
42 function decbin32( $dec ) {
43 return str_pad( decbin( $dec ), 32, '0', STR_PAD_LEFT );
44 }
45
46 // ipv4_in_range
47 // This function takes 2 arguments, an IP address and a "range" in several
48 // different formats.
49 // Network ranges can be specified as:
50 // 1. Wildcard format: 1.2.3.*
51 // 2. CIDR format: 1.2.3/24 OR 1.2.3.4/255.255.255.0
52 // 3. Start-End IP format: 1.2.3.0-1.2.3.255
53 // The function will return true if the supplied IP is within the range.
54 // Note little validation is done on the range inputs - it expects you to
55 // use one of the above 3 formats.
56 function ipv4_in_range( $ip, $range ) {
57 if ( strpos( $range, '/' ) !== false ) {
58 // $range is in IP/NETMASK format
59 list( $range, $netmask ) = explode( '/', $range, 2 );
60 if ( strpos( $netmask, '.' ) !== false ) {
61 // $netmask is a 255.255.0.0 format
62 $netmask = str_replace( '*', '0', $netmask );
63 $netmask_dec = ip2long( $netmask );
64
65 return ( ( ip2long( $ip ) & $netmask_dec ) == ( ip2long( $range ) & $netmask_dec ) );
66 } else {
67 // $netmask is a CIDR size block
68 // fix the range argument
69 $x = explode( '.', $range );
70 while ( count( $x ) < 4 ) {
71 $x[] = '0';
72 }
73 list( $a, $b, $c, $d ) = $x;
74 $range = sprintf( "%u.%u.%u.%u", empty( $a ) ? '0' : $a, empty( $b ) ? '0' : $b, empty( $c ) ? '0' : $c, empty( $d ) ? '0' : $d );
75 $range_dec = ip2long( $range );
76 $ip_dec = ip2long( $ip );
77
78 # Strategy 1 - Create the netmask with 'netmask' 1s and then fill it to 32 with 0s
79 #$netmask_dec = bindec(str_pad('', $netmask, '1') . str_pad('', 32-$netmask, '0'));
80
81 # Strategy 2 - Use math to create it
82 $wildcard_dec = pow( 2, ( 32 - $netmask ) ) - 1;
83 $netmask_dec = ~$wildcard_dec;
84
85 return ( ( $ip_dec & $netmask_dec ) == ( $range_dec & $netmask_dec ) );
86 }
87 } else {
88 // range might be 255.255.*.* or 1.2.3.0-1.2.3.255
89 if ( strpos( $range, '*' ) !== false ) { // a.b.*.* format
90 // Just convert to A-B format by setting * to 0 for A and 255 for B
91 $lower = str_replace( '*', '0', $range );
92 $upper = str_replace( '*', '255', $range );
93 $range = "$lower-$upper";
94 }
95
96 if ( strpos( $range, '-' ) !== false ) { // A-B format
97 list( $lower, $upper ) = explode( '-', $range, 2 );
98 $lower_dec = (float) sprintf( "%u", ip2long( $lower ) );
99 $upper_dec = (float) sprintf( "%u", ip2long( $upper ) );
100 $ip_dec = (float) sprintf( "%u", ip2long( $ip ) );
101
102 return ( ( $ip_dec >= $lower_dec ) && ( $ip_dec <= $upper_dec ) );
103 }
104
105 return false;
106 }
107 }
108
109 function ip2long6( $ip ) {
110 if ( substr_count( $ip, '::' ) ) {
111 $ip = str_replace( '::', str_repeat( ':0000', 8 - substr_count( $ip, ':' ) ) . ':', $ip );
112 }
113
114 $ip = explode( ':', $ip );
115 $r_ip = '';
116 foreach ( $ip as $v ) {
117 $r_ip .= str_pad( base_convert( $v, 16, 2 ), 16, 0, STR_PAD_LEFT );
118 }
119
120 return base_convert( $r_ip, 2, 10 );
121 }
122
123 // Get the ipv6 full format and return it as a decimal value.
124 function get_ipv6_full( $ip ) {
125 $pieces = explode( "/", $ip, 2 );
126 $left_piece = $pieces[0];
127 $right_piece = $pieces[1];
128
129 // Extract out the main IP pieces
130 $ip_pieces = explode( "::", $left_piece, 2 );
131 $main_ip_piece = $ip_pieces[0];
132 $last_ip_piece = $ip_pieces[1];
133
134 // Pad out the shorthand entries.
135 $main_ip_pieces = explode( ":", $main_ip_piece );
136 foreach ( $main_ip_pieces as $key => $val ) {
137 $main_ip_pieces[ $key ] = str_pad( $main_ip_pieces[ $key ], 4, "0", STR_PAD_LEFT );
138 }
139
140 // Check to see if the last IP block (part after ::) is set
141 $last_piece = "";
142 $size = count( $main_ip_pieces );
143 if ( trim( $last_ip_piece ) != "" ) {
144 $last_piece = str_pad( $last_ip_piece, 4, "0", STR_PAD_LEFT );
145
146 // Build the full form of the IPV6 address considering the last IP block set
147 for ( $i = $size; $i < 7; $i ++ ) {
148 $main_ip_pieces[ $i ] = "0000";
149 }
150 $main_ip_pieces[7] = $last_piece;
151 } else {
152 // Build the full form of the IPV6 address
153 for ( $i = $size; $i < 8; $i ++ ) {
154 $main_ip_pieces[ $i ] = "0000";
155 }
156 }
157
158 // Rebuild the final long form IPV6 address
159 $final_ip = implode( ":", $main_ip_pieces );
160
161 return $this->ip2long6( $final_ip );
162 }
163
164
165 // Determine whether the IPV6 address is within range.
166 // $ip is the IPV6 address in decimal format to check if its within the IP range created by the cloudflare IPV6 address, $range_ip.
167 // $ip and $range_ip are converted to full IPV6 format.
168 // Returns true if the IPV6 address, $ip, is within the range from $range_ip. False otherwise.
169 function ipv6_in_range( $ip, $range_ip ) {
170 $pieces = explode( "/", $range_ip, 2 );
171 $left_piece = $pieces[0];
172 $right_piece = $pieces[1];
173
174 // Extract out the main IP pieces
175 $ip_pieces = explode( "::", $left_piece, 2 );
176 $main_ip_piece = $ip_pieces[0];
177 $last_ip_piece = $ip_pieces[1];
178
179 // Pad out the shorthand entries.
180 $main_ip_pieces = explode( ":", $main_ip_piece );
181 foreach ( $main_ip_pieces as $key => $val ) {
182 $main_ip_pieces[ $key ] = str_pad( $main_ip_pieces[ $key ], 4, "0", STR_PAD_LEFT );
183 }
184
185 // Create the first and last pieces that will denote the IPV6 range.
186 $first = $main_ip_pieces;
187 $last = $main_ip_pieces;
188
189 // Check to see if the last IP block (part after ::) is set
190 $last_piece = "";
191 $size = count( $main_ip_pieces );
192 if ( trim( $last_ip_piece ) != "" ) {
193 $last_piece = str_pad( $last_ip_piece, 4, "0", STR_PAD_LEFT );
194
195 // Build the full form of the IPV6 address considering the last IP block set
196 for ( $i = $size; $i < 7; $i ++ ) {
197 $first[ $i ] = "0000";
198 $last[ $i ] = "ffff";
199 }
200 $main_ip_pieces[7] = $last_piece;
201 } else {
202 // Build the full form of the IPV6 address
203 for ( $i = $size; $i < 8; $i ++ ) {
204 $first[ $i ] = "0000";
205 $last[ $i ] = "ffff";
206 }
207 }
208
209 // Rebuild the final long form IPV6 address
210 $first = $this->ip2long6( implode( ":", $first ) );
211 $last = $this->ip2long6( implode( ":", $last ) );
212 $in_range = ( $ip >= $first && $ip <= $last );
213
214 return $in_range;
215 }
216 }
217