Revision 366de107
Added by Stilez y over 9 years ago
src/etc/inc/util.inc | ||
---|---|---|
422 | 422 |
} |
423 | 423 |
|
424 | 424 |
/* Convert long int to IPv4 address |
425 |
Returns '' if not valid IPv4 (including if any bits >32 are non-zero) */ |
|
425 |
Returns '' if not valid IPv4 (including if any bits >32 are non-zero) |
|
426 |
NOTE: The test needs care, as several methods to test whether any high bits >= 33 are set, fails on x32 platforms. |
|
427 |
The test uses ~0xFFFFFFFF which set all high bits >= 33 (if any) whatever the system INT size |
|
428 |
Alternative test if ever needed that's known to work, is: (PHP_INT_SIZE <= 4 || ($ip >> 32) == 0)) |
|
429 |
since if INT <4 bytes it's always ok and if not >>32 should be reliable. |
|
430 |
*/ |
|
426 | 431 |
function long2ip32($ip) { |
427 |
return long2ip($ip & 0xFFFFFFFF);
|
|
428 |
} |
|
432 |
return ((is_int($ip) && ($ip & ~0xFFFFFFFF) == 0) ? long2ip($ip & 0xFFFFFFFF) : '');
|
|
433 |
}
|
|
429 | 434 |
|
430 | 435 |
/* Convert IPv4 address to long int, truncated to 32-bits to avoid sign extension on 64-bit platforms. |
431 | 436 |
Returns '' if not valid IPv4. */ |
432 | 437 |
function ip2long32($ip) { |
433 |
return (ip2long($ip) & 0xFFFFFFFF); |
|
438 |
$a = ip2long($ip); |
|
439 |
return ($a === False ? '' : $a & 0xFFFFFFFF); |
|
434 | 440 |
} |
435 | 441 |
|
436 | 442 |
/* Convert IPv4 address to unsigned long int. |
437 | 443 |
Returns '' if not valid IPv4. */ |
438 | 444 |
function ip2ulong($ip) { |
439 |
return sprintf("%u", ip2long32($ip)); |
|
445 |
$a = ip2long($ip); |
|
446 |
return ($a === False ? '' : sprintf("%u", $a & 0xFFFFFFFF)); |
|
440 | 447 |
} |
441 | 448 |
|
442 | 449 |
/* Find out how many IPs are contained within a given IP range |
Also available in: Unified diff
data sanitising: ip2long32, ip2ulong, long2ip32 (FIXED RESUBMIT of #2152)
Self explanatory. If these functions find themselves trying to convert non-int data (or an x64 int with non-zeros in any bits >32) to dotted IPv4, or non-dotted IPv4 to integer IPv4 values, something's wrong and they shouldn't return a value that looks like they succeeded.
The original PR caused issues with VPN. This was because, to check the presence of any bits beyond #32 were zero (if INT was 64 bits or larger), the operator >>32 was used. Unfortunately this was undefined on x32 platforms. (See https://forum.pfsense.org/index.php?topic=104175 ).
The fix below was tested on x32, on the same thread.
TEST PR'ed IN #2152 (FAILS ON x32):
return ((is_int($ip) && ($ip >> 32) 0) ? long2ip($ip & 0xFFFFFFFF) : '');
TEST NOW USED (SEEMS RELIABLE ON ALL SYSTEM INT SIZES):
return ((is_int($ip) && ($ip & ~0xFFFFFFFF) 0) ? long2ip($ip & 0xFFFFFFFF) : '');
Other than this line and a comment, this code is identical to PR #2152